diff options
Diffstat (limited to 'chalk/ui')
210 files changed, 42414 insertions, 0 deletions
diff --git a/chalk/ui/Makefile.am b/chalk/ui/Makefile.am new file mode 100644 index 00000000..34f67c91 --- /dev/null +++ b/chalk/ui/Makefile.am @@ -0,0 +1,75 @@ +INCLUDES = \ + -I$(srcdir) \ + -I$(srcdir)/../sdk \ + -I$(srcdir)/../core \ + -I$(srcdir)/../chalkcolor \ + $(KOFFICE_INCLUDES) \ + $(KOPAINTER_INCLUDES) \ + $(KDE_INCLUDES) \ + $(all_includes) + +lib_LTLIBRARIES = libchalkui.la +libchalkui_la_LDFLAGS = -version-info 1:0:0 -no-undefined $(all_libraries) +libchalkui_la_LIBADD = ../sdk/libchalksdk.la ../core/libchalkimage.la ../chalkcolor/libchalkcolor.la \ + $(LCMS_LIBS) $(LIB_KOFFICEUI) $(LIB_KOPAINTER) $(LIB_KOPALETTE) $(LIB_XINPUTEXT) $(GLLIB) + +libchalkui_la_SOURCES = kis_import_catcher.cc kis_histogram_view.cc imageviewer.cc kcurve.cc \ + kis_autobrush.cc kis_autogradient.cc kis_boundary_painter.cc kis_brush_chooser.cc \ + kis_canvas.cc kis_canvas_painter.cc kis_clipboard.cc kis_cmb_composite.cc \ + kis_cmb_idlist.cc kis_color_cup.cc kis_config.cc kis_controlframe.cc kis_cursor.cc \ + kis_dlg_apply_profile.cc kis_dlg_image_properties.cc kis_dlg_layer_properties.cc \ + kis_dlg_new_layer.cc kis_dlg_preferences.cc kis_doc.cc kis_doc_iface.cc kis_doc_iface.skel \ + kis_double_widget.cc kis_factory.cc kis_filter_manager.cc kis_gradient_chooser.cc \ + kis_gradient_slider_widget.cc kis_icon_item.cc kis_iconwidget.cc kis_int_spinbox.cc \ + kis_itemchooser.cc kis_label_cursor_pos.cc kis_label_progress.cc kis_label_zoom.cc \ + kis_layerbox.cc kis_layerlist.cc kis_multi_bool_filter_widget.cc \ + kis_multi_double_filter_widget.cc kis_multi_integer_filter_widget.cc kis_opengl_canvas.cc \ + kis_opengl_canvas_painter.cc kis_opengl_image_context.cc kis_paintop_box.cc kis_palette_view.cc \ + kis_palette_widget.cc kis_part_layer.cc kis_pattern_chooser.cc kis_previewdialog.cc \ + kis_previewwidget.cc kis_qpaintdevice_canvas.cc kis_qpaintdevice_canvas_painter.cc \ + kis_resource_mediator.cc kis_resourceserver.cc kis_ruler.cc kis_selection_manager.cc \ + kis_selection_options.cc kis_text_brush.cc kis_tool.cc kis_tool_dummy.cc kis_tool_freehand.cc \ + kis_tool_manager.cc kis_tool_non_paint.cc kis_tool_paint.cc kis_tool_registry.cc \ + kis_tool_shape.cc kis_birdeye_box.cc kis_view.cc kis_view_iface.cc kis_custom_brush.cc \ + kis_custom_palette.cc kis_custom_pattern.cc kis_custom_image_widget.cc kis_view_iface.skel \ + kobirdeyepanel.cpp kis_matrix_widget.ui kis_previewwidgetbase.ui layerlist.cpp \ + wdgapplyprofile.ui wdgautobrush.ui wdgautogradient.ui wdgbirdeye.ui wdgcolorsettings.ui \ + wdgdisplaysettings.ui wdggeneralsettings.ui wdglayerproperties.ui wdglayerbox.ui \ + wdgnewimage.ui wdgperformancesettings.ui wdgselectionoptions.ui wdgshapeoptions.ui \ + wdgpressuresettings.ui wdgcustombrush.ui wdgcustompalette.ui wdgcustompattern.ui \ + wdgtextbrush.ui kis_dlg_adjustment_layer.cc kis_filters_listview.cc \ + wdgpalettechooser.ui wdggridsettings.ui kis_grid_manager.cpp wdgtabletdevicesettings.ui \ + wdgtabletsettings.ui kis_input_device.cc kis_part_layer_handler.cc \ + kis_dlg_adj_layer_props.cc squeezedcombobox.cpp kis_perspective_grid_manager.cpp \ + kis_grid_drawer.cpp + +noinst_HEADERS = kis_aboutdata.h imageviewer.h layerlist.h kcurve.h \ + kis_autobrush.h kis_autogradient.h kis_birdeye_box.h kis_brush_chooser.h \ + kis_button_press_event.h kis_canvas.h kis_clipboard.h kis_controlframe.h \ + kis_dlg_apply_profile.h kis_dlg_image_properties.h kis_dlg_layer_properties.h \ + kis_dlg_new_layer.h kis_dlg_preferences.h kis_event.h kis_factory.h \ + kis_label_cursor_pos.h kis_label_progress.h kis_part_layer.h kis_pattern_chooser.h \ + kis_resource_mediator.h kis_resourceserver.h kis_ruler.h kis_selection_manager.h \ + kis_selection_options.h kis_view_iface.h kis_custom_brush.h kis_custom_pattern.h \ + kis_custom_image_widget.h kis_dlg_adjustment_layer.h kis_grid_manager.h \ + kis_dlg_adj_layer_props.h squeezedcombobox.h kis_perspective_grid_manager.h + +include_HEADERS = kis_button_event.h kis_button_release_event.h kis_canvas_painter.h kis_cmb_composite.h kis_cmb_idlist.h kis_color_cup.h kis_config.h \ + kis_cursor.h kis_doc.h kis_doc_iface.h \ + kis_double_click_event.h kis_double_widget.h kis_event.h kis_filter_manager.h \ + kis_gradient_chooser.h kis_gradient_slider_widget.h kis_histogram_view.h kis_icon_item.h \ + kis_iconwidget.h kis_itemchooser.h \ + kis_label_zoom.h kis_int_spinbox.h kis_layerbox.h kis_layerlist.h kis_matrix_widget.ui.h kis_move_event.h \ + kis_multi_bool_filter_widget.h kis_multi_double_filter_widget.h kis_multi_integer_filter_widget.h \ + kis_paintop_box.h kis_palette_widget.h \ + kis_previewdialog.h kis_previewwidget.h \ + kis_tool_controller.h kis_tool.h kis_tool_non_paint.h kis_tool_paint.h kis_tool_freehand.h \ + kis_tool_dummy.h kis_tool_manager.h kis_tool_types.h kis_tool_registry.h kis_view.h \ + kis_tool_factory.h \ + kobirdeyepanel.h \ + kis_filters_listview.h kis_input_device.h kis_opengl_image_context.h + +METASOURCES = AUTO + +KDE_OPTIONS = nofinal + diff --git a/chalk/ui/imageviewer.cc b/chalk/ui/imageviewer.cc new file mode 100644 index 00000000..b6d94ed9 --- /dev/null +++ b/chalk/ui/imageviewer.cc @@ -0,0 +1,78 @@ +/*************************************************************************** + * Copyright (C) 2005 Eyal Lotem <eyal.lotem@gmail.com> * + * Copyright (C) 2005 Alexandre Oliveira <aleprj@gmail.com> * + * Copyright (C) 2006 Cyrille Berger <cberger@cberger.net> * + * * + * 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 2 of the License, 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., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#include "imageviewer.h" + +#include <tqlabel.h> +#include <tqpainter.h> +#include <tqimage.h> +#include <tqcursor.h> + +#include <kapplication.h> +#include <kdebug.h> +#include <kis_cursor.h> + +ImageViewer::ImageViewer(TQWidget *widget, const char * name) + : TQScrollView(widget, name) + , m_isDragging(false) + , m_image(TQPixmap()) +{ + m_label = new TQLabel( viewport()); + tqsetSizePolicy(TQSizePolicy::MinimumExpanding, TQSizePolicy::MinimumExpanding); + setCursor(KisCursor::handCursor()); + addChild(m_label); +} + +void ImageViewer::setImage(TQImage & image) +{ + m_image = TQPixmap(image); + m_label->setPixmap(m_image); + resizeContents( m_image.width(), m_image.height() ); + tqrepaintContents(false); +} + +void ImageViewer::contentsMousePressEvent(TQMouseEvent *event) +{ + if(Qt::LeftButton == event->button()) { + setCursor(KisCursor::closedHandCursor()); + m_currentPos = event->globalPos(); + m_isDragging = true; + } +} + +void ImageViewer::contentsMouseReleaseEvent(TQMouseEvent *event) +{ + if(Qt::LeftButton == event->button()) { + setCursor(KisCursor::handCursor()); + m_currentPos = event->globalPos(); + m_isDragging = false; + } +} + +void ImageViewer::contentsMouseMoveEvent(TQMouseEvent *event) +{ + if(m_isDragging) { + TQPoint delta = m_currentPos - event->globalPos(); + scrollBy(delta.x(), delta.y()); + m_currentPos = event->globalPos(); + } +} + +#include "imageviewer.moc" diff --git a/chalk/ui/imageviewer.h b/chalk/ui/imageviewer.h new file mode 100644 index 00000000..1865e5d0 --- /dev/null +++ b/chalk/ui/imageviewer.h @@ -0,0 +1,53 @@ +/*************************************************************************** + * Copyright (C) 2005 Eyal Lotem <eyal.lotem@gmail.com> * + * * + * 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 2 of the License, 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., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#ifndef PIXMAPVIEWER_H +#define PIXMAPVIEWER_H + +#include <tqscrollview.h> +#include <tqimage.h> + +class TQLabel; + +/** + * A scrollable image view. + * + * XXX: We should add a signal that emits newly eposed rects so the filters + * don't have to filter everything, but just the the new bits. + */ +class ImageViewer : public TQScrollView { + Q_OBJECT + TQ_OBJECT + +public: + ImageViewer(TQWidget *widget, const char * name = 0); + + void setImage(TQImage & image); + + void contentsMousePressEvent(TQMouseEvent *event); + void contentsMouseReleaseEvent(TQMouseEvent *event); + void contentsMouseMoveEvent(TQMouseEvent *event); + void wheelEvent(TQWheelEvent * event) { event->ignore(); }; +private: + TQLabel* m_label; + bool m_isDragging; + TQPoint m_currentPos; + TQPixmap m_image; +}; + +#endif diff --git a/chalk/ui/kcurve.cc b/chalk/ui/kcurve.cc new file mode 100644 index 00000000..47f9934a --- /dev/null +++ b/chalk/ui/kcurve.cc @@ -0,0 +1,450 @@ +/* ============================================================ + * Copyright 2004-2005 by Gilles Caulier + * Copyright 2005 by Casper Boemann (reworked to be generic) + * + * 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 2, 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. + * + * ============================================================ */ + +// C++ includes. + +#include <cmath> +#include <cstdlib> + +// TQt includes. + +#include <tqpixmap.h> +#include <tqpainter.h> +#include <tqpoint.h> +#include <tqpen.h> +#include <tqevent.h> +#include <tqtimer.h> +#include <tqrect.h> +#include <tqfont.h> +#include <tqfontmetrics.h> + +// KDE includes. + +#include <kdebug.h> +#include <kcursor.h> +#include <klocale.h> + +// Local includes. + +#include "kcurve.h" + +KCurve::KCurve(TQWidget *tqparent, const char *name, WFlags f) + : TQWidget(tqparent, name, f) +{ + m_grab_point = NULL; + m_readOnlyMode = false; + m_guideVisible = false; + m_dragging = false; + m_pix = NULL; + + setMouseTracking(true); + setPaletteBackgroundColor(TQt::NoBackground); + setMinimumSize(150, 50); + TQPair<double,double> *p = new TQPair<double,double>; + p->first = 0.0; p->second=0.0; + m_points.append(p); + p = new TQPair<double,double>; + p->first = 1.0; p->second=1.0; + m_points.append(p); + m_points.setAutoDelete(true); + setFocusPolicy(TQ_StrongFocus); +} + +KCurve::~KCurve() +{ + if (m_pix) delete m_pix; +} + +void KCurve::reset(void) +{ + m_grab_point = NULL; + m_guideVisible = false; + tqrepaint(false); +} + +void KCurve::setCurveGuide(TQColor color) +{ + m_guideVisible = true; + m_colorGuide = color; + tqrepaint(false); +} + +void KCurve::setPixmap(TQPixmap pix) +{ + if (m_pix) delete m_pix; + m_pix = new TQPixmap(pix); + tqrepaint(false); +} + +void KCurve::keyPressEvent(TQKeyEvent *e) +{ + if(e->key() == TQt::Key_Delete || e->key() == TQt::Key_Backspace) + { + TQPair<double,double> *closest_point=NULL; + if(m_grab_point) + { + //first find closest point to get focus afterwards + TQPair<double,double> *p = m_points.first(); + double distance = 1000; // just a big number + while(p) + { + if(p!=m_grab_point) + if (fabs (m_grab_point->first - p->first) < distance) + { + distance = fabs(m_grab_point->first - p->first); + closest_point = p; + } + p = m_points.next(); + } + m_points.remove(m_grab_point); + } + m_grab_point = closest_point; + tqrepaint(false); + } + else + TQWidget::keyPressEvent(e); +} + +void KCurve::paintEvent(TQPaintEvent *) +{ + int x, y; + int wWidth = width(); + int wHeight = height(); + + x = 0; + y = 0; + + // Drawing selection or all histogram values. + // A TQPixmap is used for enable the double buffering. + + TQPixmap pm(size()); + TQPainter p1; + p1.tqbegin(TQT_TQPAINTDEVICE(&pm), this); + + // draw background + if(m_pix) + { + p1.scale(1.0*wWidth/m_pix->width(), 1.0*wHeight/m_pix->height()); + p1.drawPixmap(0, 0, *m_pix); + p1.resetXForm(); + } + else + pm.fill(); + + // Draw grid separators. + p1.setPen(TQPen::TQPen(TQt::gray, 1, TQt::SolidLine)); + p1.drawLine(wWidth/3, 0, wWidth/3, wHeight); + p1.drawLine(2*wWidth/3, 0, 2*wWidth/3, wHeight); + p1.drawLine(0, wHeight/3, wWidth, wHeight/3); + p1.drawLine(0, 2*wHeight/3, wWidth, 2*wHeight/3); + + // Draw curve. + double curvePrevVal = getCurveValue(0.0); + p1.setPen(TQPen::TQPen(TQt::black, 1, TQt::SolidLine)); + for (x = 0 ; x < wWidth ; x++) + { + double curveX; + double curveVal; + + curveX = (x + 0.5) / wWidth; + + curveVal = getCurveValue(curveX); + + p1.drawLine(x - 1, wHeight - int(curvePrevVal * wHeight), + x, wHeight - int(curveVal * wHeight)); + + curvePrevVal = curveVal; + } + p1.drawLine(x - 1, wHeight - int(curvePrevVal * wHeight), + x, wHeight - int(getCurveValue(1.0) * wHeight)); + + // Drawing curve handles. + if ( !m_readOnlyMode ) + { + TQPair<double,double> *p = m_points.first(); + + while(p) + { + double curveX = p->first; + double curveY = p->second; + + if(p == m_grab_point) + { + p1.setPen(TQPen::TQPen(TQt::red, 3, TQt::SolidLine)); + p1.drawEllipse( int(curveX * wWidth) - 2, + wHeight - 2 - int(curveY * wHeight), 4, 4 ); + } + else + { + p1.setPen(TQPen::TQPen(TQt::red, 1, TQt::SolidLine)); + + p1.drawEllipse( int(curveX * wWidth) - 3, + wHeight - 3 - int(curveY * wHeight), 6, 6 ); + } + + p = m_points.next(); + } + } + + p1.end(); + bitBlt(this, 0, 0, &pm); +} + +void KCurve::mousePressEvent ( TQMouseEvent * e ) +{ + if (m_readOnlyMode) return; + + TQPair<double,double> *closest_point=NULL; + double distance; + + if (e->button() != Qt::LeftButton) + return; + + double x = e->pos().x() / (float)width(); + double y = 1.0 - e->pos().y() / (float)height(); + + distance = 1000; // just a big number + + TQPair<double,double> *p = m_points.first(); + int insert_pos,pos=0; + while(p) + { + if (fabs (x - p->first) < distance) + { + distance = fabs(x - p->first); + closest_point = p; + if(x < p->first) + insert_pos = pos; + else + insert_pos = pos + 1; + } + p = m_points.next(); + pos++; + } + + + if(closest_point == NULL) + { + closest_point = new TQPair<double,double>; + closest_point->first = x; + closest_point->second = y; + m_points.append(closest_point); + } + else if(distance * width() > 5) + { + closest_point = new TQPair<double,double>; + closest_point->first = x; + closest_point->second = y; + m_points.insert(insert_pos, closest_point); + } + else + if(fabs(y - closest_point->second) * width() > 5) + return; + + + m_grab_point = closest_point; + m_grabOffsetX = m_grab_point->first - x; + m_grabOffsetY = m_grab_point->second - y; + m_grab_point->first = x + m_grabOffsetX; + m_grab_point->second = y + m_grabOffsetY; + m_dragging = true; + + setCursor( KCursor::crossCursor() ); + + // Determine the leftmost and rightmost points. + m_leftmost = 0; + m_rightmost = 1; + + p = m_points.first(); + while(p) + { + if (p != m_grab_point) + { + if(p->first> m_leftmost && p->first < x) + m_leftmost = p->first; + if(p->first < m_rightmost && p->first > x) + m_rightmost = p->first; + } + p = m_points.next(); + } + tqrepaint(false); +} + +void KCurve::mouseReleaseEvent ( TQMouseEvent * e ) +{ + if (m_readOnlyMode) return; + + if (e->button() != Qt::LeftButton) + return; + + setCursor( KCursor::arrowCursor() ); + m_dragging = false; + tqrepaint(false); + emit modified(); +} + +void KCurve::mouseMoveEvent ( TQMouseEvent * e ) +{ + if (m_readOnlyMode) return; + + double x = e->pos().x() / (float)width(); + double y = 1.0 - e->pos().y() / (float)height(); + + if (m_dragging == false) // If no point is selected set the the cursor tqshape if on top + { + double distance = 1000; + double ydistance = 1000; + TQPair<double,double> *p = m_points.first(); + while(p) + { + if (fabs (x - p->first) < distance) + { + distance = fabs(x - p->first); + ydistance = fabs(y - p->second); + } + p = m_points.next(); + } + + if (distance * width() > 5 || ydistance * height() > 5) + setCursor( KCursor::arrowCursor() ); + else + setCursor( KCursor::crossCursor() ); + } + else // Else, drag the selected point + { + setCursor( KCursor::crossCursor() ); + + x += m_grabOffsetX; + y += m_grabOffsetY; + + if (x <= m_leftmost) + x = m_leftmost + 1E-4; // the addition so we can grab the dot later. + + if(x >= m_rightmost) + x = m_rightmost - 1E-4; + + if(y > 1.0) + y = 1.0; + + if(y < 0.0) + y = 0.0; + + m_grab_point->first = x; + m_grab_point->second = y; + + emit modified(); + } + + tqrepaint(false); +} + +double KCurve::getCurveValue(double x) +{ + return getCurveValue(m_points, x); +} + +double KCurve::getCurveValue(TQPtrList<TQPair<double,double> > &curve, double x) +{ + double t; + TQPair<double,double> *p; + TQPair<double,double> *p0,*p1,*p2,*p3; + double c0,c1,c2,c3; + double val; + + if(curve.count() == 0) + return 0.5; + + // First find curve segment + p = curve.first(); + if(x < p->first) + return p->second; + + p = curve.last(); + if(x >= p->first) + return p->second; + + // Find the four control points (two on each side of x) + p = curve.first(); + while(x >= p->first) + { + p = curve.next(); + } + curve.prev(); + + if((p0 = curve.prev()) == NULL) + p1 = p0 = curve.first(); + else + p1 = curve.next(); + + p2 = curve.next(); + if( (p = curve.next()) ) + p3 = p; + else + p3 = p2; + + // Calculate the value + t = (x - p1->first) / (p2->first - p1->first); + c2 = (p2->second - p0->second) * (p2->first-p1->first) / (p2->first-p0->first); + c3 = p1->second; + c0 = -2*p2->second + 2*c3 + c2 + (p3->second - p1->second) * (p2->first - p1->first) / (p3->first - p1->first); + c1 = p2->second - c3 - c2 - c0; + val = ((c0*t + c1)*t + c2)*t + c3; + + if(val < 0.0) + val = 0.0; + if(val > 1.0) + val = 1.0; + return val; +} + +TQPtrList<TQPair<double,double> > KCurve::getCurve() +{ + TQPtrList<TQPair<double,double> > outlist; + TQPair<double,double> *p; + TQPair<double,double> *outpoint; + + p = m_points.first(); + while(p) + { + outpoint = new TQPair<double,double>(p->first, p->second); + outlist.append(outpoint); + p = m_points.next(); + } + return outlist; +} + +void KCurve::setCurve(TQPtrList<TQPair<double,double> >inlist) +{ + TQPair<double,double> *p; + TQPair<double,double> *inpoint; + + m_points.clear(); + + inpoint = inlist.first(); + while(inpoint) + { + p = new TQPair<double,double>(inpoint->first, inpoint->second); + m_points.append(p); + inpoint = inlist.next(); + } +} + +void KCurve::leaveEvent( TQEvent * ) +{ +} + +#include "kcurve.moc" diff --git a/chalk/ui/kcurve.h b/chalk/ui/kcurve.h new file mode 100644 index 00000000..820b5f5a --- /dev/null +++ b/chalk/ui/kcurve.h @@ -0,0 +1,80 @@ +/* ============================================================ + * + * Copyright 2004-2005 by Gilles Caulier (original work as digikam curveswidget) + * Copyright 2005 by Casper Boemann (reworked to be generic) + * + * 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 2, 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. + * + * ============================================================ */ + +#ifndef KCURVE_H +#define KCURVE_H + +// TQt includes. + +#include <tqwidget.h> +#include <tqcolor.h> +#include <tqpair.h> +#include <tqsortedlist.h> +#include <koffice_export.h> +class KRITAUI_EXPORT KCurve : public TQWidget +{ +Q_OBJECT + TQ_OBJECT + +public: + KCurve(TQWidget *tqparent = 0, const char *name = 0, WFlags f = 0); + + virtual ~KCurve(); + + void reset(void); + void setCurveGuide(TQColor color); + void setPixmap(TQPixmap pix); + + +signals: + + void modified(void); + +protected: + + void keyPressEvent(TQKeyEvent *); + void paintEvent(TQPaintEvent *); + void mousePressEvent (TQMouseEvent * e); + void mouseReleaseEvent ( TQMouseEvent * e ); + void mouseMoveEvent ( TQMouseEvent * e ); + void leaveEvent ( TQEvent * ); + +public: + static double getCurveValue(TQPtrList<TQPair<double,double> > &curve, double x); + double getCurveValue(double x); + + TQPtrList<TQPair<double,double> > getCurve(); + void setCurve(TQPtrList<TQPair<double,double> >inlist); + +private: + double m_leftmost; + double m_rightmost; + TQPair<double,double> *m_grab_point; + bool m_dragging; + double m_grabOffsetX; + double m_grabOffsetY; + + bool m_readOnlyMode; + bool m_guideVisible; + TQColor m_colorGuide; + TQPtrList<TQPair<double,double> > m_points; + TQPixmap *m_pix; +}; + + +#endif /* KCURVE_H */ diff --git a/chalk/ui/kis_aboutdata.h b/chalk/ui/kis_aboutdata.h new file mode 100644 index 00000000..d06fd134 --- /dev/null +++ b/chalk/ui/kis_aboutdata.h @@ -0,0 +1,68 @@ +/* + * kis_aboutdata.h - part of Krayon + * + * Copyright (c) 1999-2000 Matthias Elter <me@kde.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_ABOUT_DATA_H_ +#define KIS_ABOUT_DATA_H_ + +#include <kaboutdata.h> +#include <klocale.h> +#include <kofficeversion.h> +#include <config.h> + +KAboutData * newChalkAboutData() +{ + KAboutData * aboutData = new KAboutData( "chalk", + I18N_NOOP("Chalk"), + KOFFICE_VERSION_STRING, + I18N_NOOP("KOffice image manipulation application"), + KAboutData::License_GPL, + I18N_NOOP("(c) 1999-2006 The Chalk team.\n"), + "", + "http://www.koffice.org/chalk", + "submit@bugs.kde.org"); + aboutData->addAuthor("Adrian Page", 0, "Adrian.Page@tesco.net"); + aboutData->addAuthor("Alan Horkan", 0, "", "http://www.openclipart.org"); + aboutData->addAuthor("Bart Coppens", 0, "kde@bartcoppens.be"); + aboutData->addAuthor("Boudewijn Rempt", 0, "boud@valdyas.org", "http://www.valdyas.org/fading/index.cgi"); + aboutData->addAuthor("Carsten Pfeiffer", 0, "carpdjih@cetus.zrz.tu-berlin.de"); + aboutData->addAuthor("Casper Boemann", 0, "cbr@boemann.dk"); + aboutData->addAuthor("Clarence Dang", 0, "dang@kde.org"); + aboutData->addAuthor("Cyrille Berger", 0, "cyb@lepi.org"); + aboutData->addAuthor("Dirk Schoenberger", 0, "dirk.schoenberger@sz-online.de"); + aboutData->addAuthor("Danny Allen", 0 , "danny@dannyallen.co.uk"); + aboutData->addAuthor("Emanuele Tamponi", 0, "emanuele@valinor.it"); + aboutData->addAuthor("Gábor Lehel", 0, "<illissius@gmail.com>"); + aboutData->addAuthor("John Califf",0, "jcaliff@compuzone.net"); + aboutData->addAuthor("Laurent Montel",0, "lmontel@mandrakesoft.com"); + aboutData->addAuthor("Matthias Elter", 0, "me@kde.org"); + aboutData->addAuthor("Melchior Franz", 0, "mfranz@kde.org"); + aboutData->addAuthor("Michael Koch", 0, "koch@kde.org"); + aboutData->addAuthor("Michael Thaler", 0, "michael.thaler@physik.tu-muenchen.de"); + aboutData->addAuthor("Patrick Julien", 0, "freak@codepimps.org"); + aboutData->addAuthor("Roger Larsson", 0, "roger.larsson@norran.net"); + aboutData->addAuthor("Sven Langkamp", 0, "longamp@reallygood.de"); + aboutData->addAuthor("Toshitaka Fujioka", 0, "fujioka@kde.org"); + aboutData->addAuthor("Thomas Zander", 0, "zander@kde.org"); + aboutData->addAuthor("Sander Koning", 0, "sanderkoning@kde.nl"); + aboutData->addAuthor("Ronan Zeegers",/*"icons"*/ 0,0); + aboutData->addAuthor("Frédéric Coiffier", 0, "frederic.coiffier@free.fr"); + return aboutData; +} + +#endif // KIS_ABOUT_DATA_H_ diff --git a/chalk/ui/kis_autobrush.cc b/chalk/ui/kis_autobrush.cc new file mode 100644 index 00000000..3d081188 --- /dev/null +++ b/chalk/ui/kis_autobrush.cc @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2004 Cyrille Berger <cberger@cberger.net> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_autobrush.h" +#include <KoImageResource.h> +#include <kdebug.h> +#include <tqspinbox.h> +#include <tqtoolbutton.h> +#include <tqimage.h> +#include <tqcombobox.h> +#include <tqlabel.h> + + +KisAutobrush::KisAutobrush(TQWidget *tqparent, const char* name, const TQString& caption) : KisWdgAutobrush(tqparent, name) +{ + setCaption(caption); + + m_linkSize = true; + m_linkFade = true; + + linkFadeToggled(m_linkSize); + linkSizeToggled(m_linkFade); + + connect(bnLinkSize, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(linkSizeToggled( bool ))); + connect(bnLinkFade, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(linkFadeToggled( bool ))); + + connect((TQObject*)comboBoxShape, TQT_SIGNAL(activated(int)), this, TQT_SLOT(paramChanged())); + spinBoxWidth->setMinValue(1); + connect(spinBoxWidth,TQT_SIGNAL(valueChanged(int)),this,TQT_SLOT(spinBoxWidthChanged(int))); + spinBoxHeigth->setMinValue(1); + connect(spinBoxHeigth,TQT_SIGNAL(valueChanged(int)),this,TQT_SLOT(spinBoxHeigthChanged(int))); + spinBoxHorizontal->setMinValue(0); + connect(spinBoxHorizontal,TQT_SIGNAL(valueChanged(int)),this,TQT_SLOT(spinBoxHorizontalChanged(int))); + spinBoxVertical->setMinValue(0); + connect(spinBoxVertical,TQT_SIGNAL(valueChanged(int)),this,TQT_SLOT(spinBoxVerticalChanged(int))); + + m_brsh = new TQImage(1,1,32); + Q_CHECK_PTR(m_brsh); + + paramChanged(); + + + connect(brushPreview, TQT_SIGNAL(clicked()), TQT_SLOT(paramChanged())); + +} + +void KisAutobrush::resizeEvent ( TQResizeEvent * ) +{ + brushPreview->setMinimumHeight(brushPreview->width()); // dirty hack ! + brushPreview->setMaximumHeight(brushPreview->width()); // dirty hack ! +} + +void KisAutobrush::activate() +{ + paramChanged(); +} + +void KisAutobrush::paramChanged() +{ + TQ_INT32 fh = TQMIN( spinBoxWidth->value()/2, spinBoxHorizontal->value() ) ; + TQ_INT32 fv = TQMIN( spinBoxHeigth->value()/2, spinBoxVertical->value() ); + KisAutobrushShape* kas; + + if(comboBoxShape->currentItem() == 0) // use index compare instead of comparing a translatable string + { + kas = new KisAutobrushCircleShape(spinBoxWidth->value(), spinBoxHeigth->value(), fh, fv); + Q_CHECK_PTR(kas); + + } else { + kas = new KisAutobrushRectShape(spinBoxWidth->value(), spinBoxHeigth->value(), fh, fv); + Q_CHECK_PTR(kas); + + } + kas->createBrush(m_brsh); + + TQPixmap p; + TQImage pi(*m_brsh); + double coeff = 1.0; + int bPw = brushPreview->width()-3; + if(pi.width() > bPw) + { + coeff = bPw /(double)pi.width(); + } + int bPh = brushPreview->height()-3; + if(pi.height() > coeff * bPh) + { + coeff = bPh /(double)pi.height(); + } + if( coeff < 1.0) + { + pi = pi.smoothScale( (int)(coeff * pi.width()) , (int)(coeff * pi.height())); + } + + p.convertFromImage(pi); + brushPreview->setPixmap(p); + KisAutobrushResource * resource = new KisAutobrushResource(*m_brsh); + Q_CHECK_PTR(resource); + + emit(activatedResource(resource)); + delete kas; +} +void KisAutobrush::spinBoxWidthChanged(int a) +{ + spinBoxHorizontal->setMaxValue(a/2); + if(m_linkSize) + { + spinBoxHeigth->setValue(a); + spinBoxVertical->setMaxValue(a/2); + } + this->paramChanged(); +} +void KisAutobrush::spinBoxHeigthChanged(int a) +{ + spinBoxVertical->setMaxValue(a/2); + if(m_linkSize) + { + spinBoxWidth->setValue(a); + spinBoxHorizontal->setMaxValue(a/2); + } + this->paramChanged(); +} +void KisAutobrush::spinBoxHorizontalChanged(int a) +{ + if(m_linkFade) + spinBoxVertical->setValue(a); + this->paramChanged(); +} +void KisAutobrush::spinBoxVerticalChanged(int a) +{ + if(m_linkFade) + spinBoxHorizontal->setValue(a); + this->paramChanged(); +} + +void KisAutobrush::linkSizeToggled(bool b) +{ + m_linkSize = b; + + KoImageResource kir; + if (b) { + bnLinkSize->setPixmap(kir.chain()); + } + else { + bnLinkSize->setPixmap(kir.chainBroken()); + } +} + +void KisAutobrush::linkFadeToggled(bool b) +{ + m_linkFade = b; + + KoImageResource kir; + if (b) { + bnLinkFade->setPixmap(kir.chain()); + } + else { + bnLinkFade->setPixmap(kir.chainBroken()); + } +} + + +#include "kis_autobrush.moc" diff --git a/chalk/ui/kis_autobrush.h b/chalk/ui/kis_autobrush.h new file mode 100644 index 00000000..92b8509d --- /dev/null +++ b/chalk/ui/kis_autobrush.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2004 Cyrille Berger <cberger@cberger.net> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _KIS_AUTOBRUSH_H_ +#define _KIS_AUTOBRUSH_H_ + +#include <tqobject.h> +#include "wdgautobrush.h" +#include <kis_autobrush_resource.h> + +class KisAutobrush : public KisWdgAutobrush +{ + Q_OBJECT + TQ_OBJECT +public: + KisAutobrush(TQWidget *tqparent, const char* name, const TQString& caption); + void activate(); + +signals: + void activatedResource(KisResource *r); + +private slots: + void paramChanged(); + void spinBoxWidthChanged(int ); + void spinBoxHeigthChanged(int ); + void spinBoxHorizontalChanged(int); + void spinBoxVerticalChanged(int); + void linkSizeToggled(bool); + void linkFadeToggled(bool); + +protected: + virtual void resizeEvent ( TQResizeEvent * ); + +private: + TQImage* m_brsh; + bool m_linkSize; + bool m_linkFade; +}; + + +#endif diff --git a/chalk/ui/kis_autogradient.cc b/chalk/ui/kis_autogradient.cc new file mode 100644 index 00000000..86b755f9 --- /dev/null +++ b/chalk/ui/kis_autogradient.cc @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2004 Cyrille Berger <cberger@cberger.net> + * 2004 Sven Langkamp <longamp@reallygood.de> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_autogradient.h" + +#include <tqpainter.h> +#include <tqcombobox.h> + +#include <kcolorbutton.h> +#include <knuminput.h> +#include "kis_int_spinbox.h" +#include "kis_gradient.h" +#include "kis_autogradient_resource.h" + +#include "kis_gradient_slider_widget.h" + +/****************************** KisAutogradient ******************************/ + +KisAutogradient::KisAutogradient(TQWidget *tqparent, const char* name, const TQString& caption) : KisWdgAutogradient(tqparent, name) +{ + setCaption(caption); + m_autogradientResource = new KisAutogradientResource(); + m_autogradientResource->createSegment( INTERP_LINEAR, COLOR_INTERP_RGB, 0.0, 1.0, 0.5, TQt::black, TQt::white ); + connect(gradientSlider, TQT_SIGNAL( sigSelectedSegment( KisGradientSegment* ) ), TQT_SLOT( slotSelectedSegment(KisGradientSegment*) )); + connect(gradientSlider, TQT_SIGNAL( sigChangedSegment(KisGradientSegment*) ), TQT_SLOT( slotChangedSegment(KisGradientSegment*) )); + gradientSlider->setGradientResource( m_autogradientResource ); + connect(comboBoxColorInterpolationType, TQT_SIGNAL( activated(int) ), TQT_SLOT( slotChangedColorInterpolation(int) )); + connect(comboBoxInterpolationType, TQT_SIGNAL( activated(int) ), TQT_SLOT( slotChangedInterpolation(int) )); + connect(leftColorButton, TQT_SIGNAL( changed(const TQColor&) ), TQT_SLOT( slotChangedLeftColor(const TQColor&) )); + connect(rightColorButton, TQT_SIGNAL( changed(const TQColor&) ), TQT_SLOT( slotChangedRightColor(const TQColor&) )); + +// intNumInputLeftOpacity->setRange( 0, 100, false); + connect(intNumInputLeftOpacity, TQT_SIGNAL( valueChanged(int) ), TQT_SLOT( slotChangedLeftOpacity(int) )); +// intNumInputRightOpacity->setRange( 0, 100, false); + connect(intNumInputRightOpacity, TQT_SIGNAL( valueChanged(int) ), TQT_SLOT( slotChangedRightOpacity(int) )); + +} + +void KisAutogradient::activate() +{ + paramChanged(); +} + +void KisAutogradient::slotSelectedSegment(KisGradientSegment* segment) +{ + leftColorButton->setColor( segment->startColor().color() ); + rightColorButton->setColor( segment->endColor().color() ); + comboBoxColorInterpolationType->setCurrentItem( segment->colorInterpolation() ); + comboBoxInterpolationType->setCurrentItem( segment->interpolation() ); + + int leftOpacity = tqRound(segment->startColor().alpha() * 100); + intNumInputLeftOpacity->setValue( leftOpacity ); + + int rightOpacity = tqRound(segment->endColor().alpha() * 100); + intNumInputRightOpacity->setValue( rightOpacity ); + + paramChanged(); +} + +void KisAutogradient::slotChangedSegment(KisGradientSegment*) +{ + paramChanged(); +} + +void KisAutogradient::slotChangedInterpolation(int type) +{ + KisGradientSegment* segment = gradientSlider->selectedSegment(); + if(segment) + segment->setInterpolation( type ); + gradientSlider->update(); + + paramChanged(); +} + +void KisAutogradient::slotChangedColorInterpolation(int type) +{ + KisGradientSegment* segment = gradientSlider->selectedSegment(); + if(segment) + segment->setColorInterpolation( type ); + gradientSlider->update(); + + paramChanged(); +} + +void KisAutogradient::slotChangedLeftColor( const TQColor& color) +{ + KisGradientSegment* segment = gradientSlider->selectedSegment(); + if(segment) + segment->setStartColor( Color( color, segment->startColor().alpha() ) ); + gradientSlider->update(); + + paramChanged(); +} + +void KisAutogradient::slotChangedRightColor( const TQColor& color) +{ + KisGradientSegment* segment = gradientSlider->selectedSegment(); + if(segment) + segment->setEndColor( Color( color, segment->endColor().alpha() ) ); + gradientSlider->tqrepaint(); + + paramChanged(); +} + +void KisAutogradient::slotChangedLeftOpacity( int value ) +{ + KisGradientSegment* segment = gradientSlider->selectedSegment(); + if(segment) + segment->setStartColor( Color( segment->startColor().color(), (double)value / 100 ) ); + gradientSlider->tqrepaint(false); + + paramChanged(); +} + +void KisAutogradient::slotChangedRightOpacity( int value ) +{ + KisGradientSegment* segment = gradientSlider->selectedSegment(); + if(segment) + segment->setEndColor( Color( segment->endColor().color(), (double)value / 100 ) ); + gradientSlider->tqrepaint(false); + + paramChanged(); +} + +void KisAutogradient::paramChanged() +{ + m_autogradientResource->updatePreview (); + emit activatedResource( m_autogradientResource ); +} + +#include "kis_autogradient.moc" diff --git a/chalk/ui/kis_autogradient.h b/chalk/ui/kis_autogradient.h new file mode 100644 index 00000000..7399aa67 --- /dev/null +++ b/chalk/ui/kis_autogradient.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2004 Cyrille Berger <cberger@cberger.net> + * 2004 Sven Langkamp <longamp@reallygood.de> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _KIS_AUTOGRADIENT_H_ +#define _KIS_AUTOGRADIENT_H_ + +#include "wdgautogradient.h" + +class KisResource; +class KisGradientSegment; +class KisAutogradientResource; + +class KisAutogradient : public KisWdgAutogradient +{ + Q_OBJECT + TQ_OBJECT + + public: + KisAutogradient(TQWidget *tqparent, const char* name, const TQString& caption); + void activate(); + signals: + void activatedResource(KisResource *r); + private: + KisAutogradientResource* m_autogradientResource; + private slots: + void slotSelectedSegment(KisGradientSegment* segment); + void slotChangedSegment(KisGradientSegment* segment); + void slotChangedInterpolation(int type); + void slotChangedColorInterpolation(int type); + void slotChangedLeftColor( const TQColor& color); + void slotChangedRightColor( const TQColor& color); + void slotChangedLeftOpacity( int value ); + void slotChangedRightOpacity( int value ); + void paramChanged(); +}; + +#endif diff --git a/chalk/ui/kis_birdeye_box.cc b/chalk/ui/kis_birdeye_box.cc new file mode 100644 index 00000000..1484563f --- /dev/null +++ b/chalk/ui/kis_birdeye_box.cc @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2004 Kivio Team + * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "tqlayout.h" +#include "tqlabel.h" +#include "tqpixmap.h" +#include "tqpainter.h" +#include "tqimage.h" +#include "config.h" +#include LCMS_HEADER +#include "klocale.h" +#include "tqtooltip.h" + +#include "kis_view.h" +#include "kis_doc.h" +#include "kis_canvas_controller.h" +#include "kis_birdeye_box.h" +#include "kis_double_widget.h" +#include "kis_canvas.h" +#include "kis_image.h" +#include "kis_rect.h" +#include "kis_iterators_pixel.h" + +#include "kobirdeyepanel.h" + +namespace { + + class CanvasAdapter : public KoCanvasAdapter { + + public: + CanvasAdapter(KisCanvasSubject * canvasSubject) : KoCanvasAdapter(), m_canvasSubject(canvasSubject) {} + virtual ~CanvasAdapter() {} + + public: + + virtual KoRect visibleArea() + { + if (!m_canvasSubject->currentImg()) return KoRect(0,0,0,0); + + KisCanvasController * c = m_canvasSubject->canvasController(); + + if (c && c->kiscanvas()) + return c->viewToWindow(KisRect(0, 0, c->kiscanvas()->width(), c->kiscanvas()->height())); + else + return KoRect(0,0,0,0); + } + + virtual double zoomFactor() + { + return m_canvasSubject->zoomFactor(); + } + + virtual TQRect size() + { + if (!m_canvasSubject->currentImg()) return TQRect(0,0,0,0); + + return TQRect(0, 0, m_canvasSubject->currentImg()->width(), m_canvasSubject->currentImg()->height()); + } + + virtual void setViewCenterPoint(double x, double y) + { + m_canvasSubject->canvasController()->zoomAroundPoint(x, y, m_canvasSubject->zoomFactor()); + } + + private: + + KisCanvasSubject * m_canvasSubject; + + }; + + class ZoomListener : public KoZoomAdapter { + + public: + + ZoomListener(KisCanvasController * canvasController) + : KoZoomAdapter() + , m_canvasController(canvasController) {} + virtual ~ZoomListener() {} + + public: + + void zoomTo( double x, double y, double factor ) { m_canvasController->zoomAroundPoint(x, y, factor); } + void zoomIn() { m_canvasController->zoomIn(); } + void zoomOut() { m_canvasController->zoomOut(); } + double getMinZoom() { return (1.0 / 500); } + double getMaxZoom() { return 16.0; } + + private: + + KisCanvasController * m_canvasController; + + }; + + class ThumbnailProvider : public KoThumbnailAdapter { + + public: + ThumbnailProvider(KisImageSP image, KisCanvasSubject* canvasSubject) + : KoThumbnailAdapter() + , m_image(image) + , m_canvasSubject(canvasSubject) {} + + virtual ~ThumbnailProvider() {} + + public: + + virtual TQSize pixelSize() + { + if (!m_image) return TQSize(0, 0); + return TQSize(m_image->width(), m_image->height()); + } + + virtual TQImage image(TQRect r, TQSize thumbnailSize) + { + if (!m_image || r.isEmpty() || thumbnailSize.width() == 0 || thumbnailSize.height() == 0) { + return TQImage(); + } + + KisPaintDevice thumbnailRect(m_image->colorSpace(), "thumbnailRect"); + KisPaintDeviceSP mergedImage = m_image->projection(); + + TQ_INT32 imageWidth = m_image->width(); + TQ_INT32 imageHeight = m_image->height(); + TQ_UINT32 pixelSize = m_image->colorSpace()->pixelSize(); + + for (TQ_INT32 y = 0; y < r.height(); ++y) { + + KisHLineIteratorPixel it = thumbnailRect.createHLineIterator(0, y, r.width(), true); + TQ_INT32 thumbnailY = r.y() + y; + TQ_INT32 thumbnailX = r.x(); + TQ_INT32 imageY = (thumbnailY * imageHeight) / thumbnailSize.height(); + KisHLineIteratorPixel srcIt = mergedImage -> createHLineIterator(0, imageY, imageWidth, false); + + while (!it.isDone()) { + + TQ_INT32 imageX = (thumbnailX * imageWidth) / thumbnailSize.width(); + TQ_INT32 dx = imageX - srcIt.x(); + srcIt += dx; + + //KisColor pixelColor = mergedImage->colorAt(imageX, imageY); + memcpy(it.rawData(), srcIt.rawData(), pixelSize); + + ++it; + ++thumbnailX; + } + } + + return thumbnailRect.convertToTQImage(m_canvasSubject->monitorProfile(), 0, 0, r.width(), r.height(), + m_canvasSubject->HDRExposure()); + } + + void setImage(KisImageSP image) + { + m_image = image; + } + private: + + KisImageSP m_image; + KisCanvasSubject * m_canvasSubject; + + }; + +} + +KisBirdEyeBox::KisBirdEyeBox(KisView * view, TQWidget* tqparent, const char* name) + : TQWidget(tqparent, name) + , m_view(view) + , m_subject(view->canvasSubject()) +{ + TQVBoxLayout * l = new TQVBoxLayout(this); + + m_image = m_subject->currentImg(); + + m_zoomAdapter = new ZoomListener(m_subject->canvasController()); // The birdeye panel deletes + KoThumbnailAdapter * ktp = new ThumbnailProvider(m_image, m_subject); // The birdeye panel deletes + KoCanvasAdapter * kpc = new CanvasAdapter(m_subject); // The birdeye panel deletes + + m_birdEyePanel = new KoBirdEyePanel(m_zoomAdapter, ktp, kpc, this); + + connect(view, TQT_SIGNAL(cursorPosition( TQ_INT32, TQ_INT32 )), m_birdEyePanel, TQT_SLOT(cursorPosChanged( TQ_INT32, TQ_INT32 ))); + connect(view, TQT_SIGNAL(viewTransformationsChanged()), m_birdEyePanel, TQT_SLOT(slotViewTransformationChanged())); + + l->addWidget(m_birdEyePanel); + + TQHBoxLayout * hl = new TQHBoxLayout(l); + + m_exposureLabel = new TQLabel(i18n("Exposure:"), this); + hl->addWidget(m_exposureLabel); + + m_exposureDoubleWidget = new KisDoubleWidget(-10, 10, this); + m_exposureDoubleWidget->tqsetSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::Fixed); + hl->addWidget(m_exposureDoubleWidget); + TQToolTip::add(m_exposureDoubleWidget, i18n("Select the exposure (stops) for HDR images")); + l->addItem(new TQSpacerItem(0, 1, TQSizePolicy::Minimum, TQSizePolicy::MinimumExpanding)); + + m_exposureDoubleWidget->setPrecision(1); + m_exposureDoubleWidget->setValue(0); + m_exposureDoubleWidget->setLineStep(0.1); + m_exposureDoubleWidget->setPageStep(1); + + connect(m_exposureDoubleWidget, TQT_SIGNAL(valueChanged(double)), TQT_SLOT(exposureValueChanged(double))); + connect(m_exposureDoubleWidget, TQT_SIGNAL(sliderPressed()), TQT_SLOT(exposureSliderPressed())); + connect(m_exposureDoubleWidget, TQT_SIGNAL(sliderReleased()), TQT_SLOT(exposureSliderReleased())); + + m_draggingExposureSlider = false; + + Q_ASSERT(m_subject->document() != 0); + connect(m_subject->document(), TQT_SIGNAL(sigCommandExecuted()), TQT_SLOT(slotDocCommandExecuted())); + + if (m_image) { + connect(m_image, TQT_SIGNAL(sigImageUpdated(TQRect)), TQT_SLOT(slotImageUpdated(TQRect))); + } +} + +KisBirdEyeBox::~KisBirdEyeBox() +{ + // Huh? Why does this cause a crash? + // delete m_zoomAdapter; +} + +void KisBirdEyeBox::setImage(KisImageSP image) +{ + if (m_image) { + m_image->disconnect(this); + } + + m_image = image; + + KoThumbnailAdapter * ktp = new ThumbnailProvider(m_image, m_subject); + m_birdEyePanel->setThumbnailProvider(ktp); + + if (m_image) { + connect(m_image, TQT_SIGNAL(sigImageUpdated(TQRect)), TQT_SLOT(slotImageUpdated(TQRect))); + connect(m_image, TQT_SIGNAL(sigSizeChanged(TQ_INT32, TQ_INT32)), TQT_SLOT(slotImageSizeChanged(TQ_INT32, TQ_INT32))); + connect(m_image, TQT_SIGNAL(sigColorSpaceChanged(KisColorSpace *)), TQT_SLOT(slotImageColorSpaceChanged(KisColorSpace *))); + m_birdEyePanel->slotUpdate(m_image->bounds()); + slotImageColorSpaceChanged(m_image->colorSpace()); + } +} + +void KisBirdEyeBox::slotDocCommandExecuted() +{ + if (m_image) { + if (!m_dirtyRect.isEmpty()) { + m_birdEyePanel->slotUpdate(m_dirtyRect); + } + m_dirtyRect = TQRect(); + } +} + +void KisBirdEyeBox::slotImageUpdated(TQRect r) +{ + m_dirtyRect |= r; +} + +void KisBirdEyeBox::slotImageSizeChanged(TQ_INT32 /*w*/, TQ_INT32 /*h*/) +{ + if (m_image) { + m_birdEyePanel->slotUpdate(m_image->bounds()); + } +} + +void KisBirdEyeBox::slotImageColorSpaceChanged(KisColorSpace *cs) +{ + if (cs->hasHighDynamicRange()) { + m_exposureDoubleWidget->show(); + m_exposureLabel->show(); + } else { + m_exposureDoubleWidget->hide(); + m_exposureLabel->hide(); + } +} + +void KisBirdEyeBox::exposureValueChanged(double exposure) +{ + if (!m_draggingExposureSlider) { + m_subject->setHDRExposure(exposure); + + if (m_image && m_image->colorSpace()->hasHighDynamicRange()) { + m_birdEyePanel->slotUpdate(m_image->bounds()); + } + } +} + +void KisBirdEyeBox::exposureSliderPressed() +{ + m_draggingExposureSlider = true; +} + +void KisBirdEyeBox::exposureSliderReleased() +{ + m_draggingExposureSlider = false; + exposureValueChanged(m_exposureDoubleWidget->value()); +} + +#include "kis_birdeye_box.moc" diff --git a/chalk/ui/kis_birdeye_box.h b/chalk/ui/kis_birdeye_box.h new file mode 100644 index 00000000..b9550474 --- /dev/null +++ b/chalk/ui/kis_birdeye_box.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2004 Kivio Team + * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_BIRDEYE_BOX_H +#define KIS_BIRDEYE_BOX_H + +#include "tqwidget.h" + +#include "kis_types.h" + +class KoBirdEyePanel; +class KisDoubleWidget; +class KisView; +class KisCanvasSubject; +class KoZoomAdapter; +class KisColorSpace; + +class KisBirdEyeBox : public TQWidget +{ + Q_OBJECT + TQ_OBJECT + +public: + + KisBirdEyeBox(KisView * view, TQWidget * tqparent = 0, const char* name=0); + ~KisBirdEyeBox(); + + void setImage(KisImageSP image); + +public slots: + void slotDocCommandExecuted(); + void slotImageUpdated(TQRect r); + void slotImageSizeChanged(TQ_INT32 w, TQ_INT32 h); + void slotImageColorSpaceChanged(KisColorSpace *cs); + +protected slots: + void exposureValueChanged(double exposure); + void exposureSliderPressed(); + void exposureSliderReleased(); + +private: + KoBirdEyePanel * m_birdEyePanel; + KisDoubleWidget * m_exposureDoubleWidget; + TQLabel *m_exposureLabel; + KisView * m_view; + KisCanvasSubject * m_subject; + bool m_draggingExposureSlider; + KoZoomAdapter * m_zoomAdapter; + KisImageSP m_image; + TQRect m_dirtyRect; +}; + +#endif // KIS_BIRDEYE_BOX_H diff --git a/chalk/ui/kis_boundary_painter.cc b/chalk/ui/kis_boundary_painter.cc new file mode 100644 index 00000000..b07bcb51 --- /dev/null +++ b/chalk/ui/kis_boundary_painter.cc @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2005 Bart Coppens <kde@bartcoppens.be> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include <tqpixmap.h> +#include <tqpainter.h> + +#include "kis_boundary.h" +#include "kis_boundary_painter.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" + +TQPixmap KisBoundaryPainter::createPixmap(const KisBoundary& boundary, int w, int h) +{ + TQPixmap target(w, h); + KisCanvasPainter painter(TQT_TQPAINTDEVICE(&target)); + + painter.eraseRect(0, 0, w, h); + + paint(boundary, painter); + + painter.end(); + return target; +} + +void KisBoundaryPainter::paint(const KisBoundary& boundary, KisCanvasPainter& painter) +{ + KisBoundary::PointPairListList::const_iterator it = boundary.m_horSegments.constBegin(); + KisBoundary::PointPairListList::const_iterator end = boundary.m_horSegments.constEnd(); + + //Qt::Horizontal + while (it != end) { + KisBoundary::PointPairList::const_iterator lineIt = (*it).constBegin(); + KisBoundary::PointPairList::const_iterator lineEnd = (*it).constEnd(); + while (lineIt != lineEnd) { + int x1 = (*lineIt).first.floorX(); + int y = (*lineIt).first.floorY(); + int x2 = x1 + (*lineIt).second; + + painter.drawLine(x1, y, x2, y); + painter.drawPoint(x2, y); + + ++lineIt; + } + ++it; + } + + //Qt::Vertical + it = boundary.m_vertSegments.constBegin(); + end = boundary.m_vertSegments.constEnd(); + + while (it != end) { + KisBoundary::PointPairList::const_iterator lineIt = (*it).constBegin(); + KisBoundary::PointPairList::const_iterator lineEnd = (*it).constEnd(); + while (lineIt != lineEnd) { + int x = (*lineIt).first.floorX(); + int y1 = (*lineIt).first.floorY(); + int y2 = y1 + (*lineIt).second; + + painter.drawLine(x, y1, x, y2); + painter.drawPoint(x, y2); + + ++lineIt; + } + ++it; + } +} + diff --git a/chalk/ui/kis_boundary_painter.h b/chalk/ui/kis_boundary_painter.h new file mode 100644 index 00000000..c8f18cd4 --- /dev/null +++ b/chalk/ui/kis_boundary_painter.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2005 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef _KIS_BOUNDARY_PAINTER_H_ +#define _KIS_BOUNDARY_PAINTER_H_ + +#include <koffice_export.h> + +class KisBoundary; +class KisCanvasPainter; + +class KRITACORE_EXPORT KisBoundaryPainter { +public: + static void paint(const KisBoundary& boundary, KisCanvasPainter& painter); + static TQPixmap createPixmap(const KisBoundary& boundary, int w, int h); +}; + +#endif // _KIS_BOUNDARY_PAINTER_H_ + diff --git a/chalk/ui/kis_brush_chooser.cc b/chalk/ui/kis_brush_chooser.cc new file mode 100644 index 00000000..69aeafdf --- /dev/null +++ b/chalk/ui/kis_brush_chooser.cc @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2004 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqcheckbox.h> +#include <klocale.h> +#include <koIconChooser.h> + +#include "kis_double_widget.h" +#include "kis_brush_chooser.h" +#include "kis_global.h" +#include "kis_icon_item.h" +#include "kis_brush.h" + +KisBrushChooser::KisBrushChooser(TQWidget *tqparent, const char *name) + : super(tqparent, name) +{ + m_lbSpacing = new TQLabel(i18n("Spacing:"), this); + m_slSpacing = new KisDoubleWidget(0.0, 10, this, "double_widget"); + m_slSpacing->setTickmarks(TQSlider::Below); + m_slSpacing->setTickInterval(1); + TQObject::connect(m_slSpacing, TQT_SIGNAL(valueChanged(double)), this, TQT_SLOT(slotSetItemSpacing(double))); + + m_chkColorMask = new TQCheckBox(i18n("Use color as tqmask"), this); + TQObject::connect(m_chkColorMask, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotSetItemUseColorAsMask(bool))); + + m_lbName = new TQLabel(this); + + TQVBoxLayout *mainLayout = new TQVBoxLayout(this, 2, -1, "main tqlayout"); + + mainLayout->addWidget(m_lbName); + mainLayout->addWidget(chooserWidget(), 10); + + TQGridLayout *spacingLayout = new TQGridLayout( 2, 2); + + mainLayout->addLayout(spacingLayout, 1); + + spacingLayout->addWidget(m_lbSpacing, 0, 0); + spacingLayout->addWidget(m_slSpacing, 0, 1); + + spacingLayout->addMultiCellWidget(m_chkColorMask, 1, 1, 0, 1); +} + +KisBrushChooser::~KisBrushChooser() +{ +} + +void KisBrushChooser::slotSetItemSpacing(double spacingValue) +{ + KisIconItem *item = static_cast<KisIconItem *>(currentItem()); + + if (item) { + KisBrush *brush = static_cast<KisBrush *>(item->resource()); + brush->setSpacing(spacingValue); + } +} + +void KisBrushChooser::slotSetItemUseColorAsMask(bool useColorAsMask) +{ + KisIconItem *item = static_cast<KisIconItem *>(currentItem()); + + if (item) { + KisBrush *brush = static_cast<KisBrush *>(item->resource()); + brush->setUseColorAsMask(useColorAsMask); + item->updatePixmaps(); + emit selected(currentItem()); + } +} + +void KisBrushChooser::update(KoIconItem *item) +{ + KisIconItem *kisItem = static_cast<KisIconItem *>(item); + + if (kisItem) { + KisBrush *brush = static_cast<KisBrush *>(kisItem->resource()); + + TQString text = TQString("%1 (%2 x %3)").tqarg(brush->name()).tqarg(brush->width()).tqarg(brush->height()); + + m_lbName->setText(text); + m_slSpacing->setValue(brush->spacing()); + m_chkColorMask->setChecked(brush->useColorAsMask()); + m_chkColorMask->setEnabled(brush->hasColor()); + } +} + +#include "kis_brush_chooser.moc" + diff --git a/chalk/ui/kis_brush_chooser.h b/chalk/ui/kis_brush_chooser.h new file mode 100644 index 00000000..99438e70 --- /dev/null +++ b/chalk/ui/kis_brush_chooser.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2004 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_BRUSH_CHOOSER_H_ +#define KIS_BRUSH_CHOOSER_H_ + +#include "kis_itemchooser.h" + +class TQLabel; +class TQCheckBox; + +class KisDoubleWidget; + +class KisBrushChooser : public KisItemChooser { + typedef KisItemChooser super; + Q_OBJECT + TQ_OBJECT + +public: + KisBrushChooser(TQWidget *tqparent = 0, const char *name = 0); + virtual ~KisBrushChooser(); + +protected: + virtual void update(KoIconItem *item); + +private slots: + void slotSetItemSpacing(double spacing); + void slotSetItemUseColorAsMask(bool); + +private: + TQLabel *m_lbName; + TQLabel *m_lbSpacing; + KisDoubleWidget *m_slSpacing; + TQCheckBox *m_chkColorMask; +}; + +#endif // KIS_BRUSH_CHOOSER_H_ + diff --git a/chalk/ui/kis_button_event.h b/chalk/ui/kis_button_event.h new file mode 100644 index 00000000..f9b6a385 --- /dev/null +++ b/chalk/ui/kis_button_event.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2004 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_BUTTON_EVENT_H_ +#define KIS_BUTTON_EVENT_H_ + +#include "kis_event.h" + +class KisButtonEvent : public KisEvent { + typedef KisEvent super; +public: + TQt::ButtonState button() const { return m_button; } + +protected: + KisButtonEvent() {} + KisButtonEvent(enumEventType type, + KisInputDevice device, + const KisPoint& pos, + const KisPoint& globalPos, + double pressure, + double xTilt, double yTilt, + TQt::ButtonState button, + TQt::ButtonState state) + : super(type, device, pos, globalPos, pressure, xTilt, yTilt, state) + , m_button(button) {} + + TQt::ButtonState m_button; +}; + +#endif // KIS_BUTTON_EVENT_H_ + diff --git a/chalk/ui/kis_button_press_event.h b/chalk/ui/kis_button_press_event.h new file mode 100644 index 00000000..20dfafc6 --- /dev/null +++ b/chalk/ui/kis_button_press_event.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2004 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_BUTTON_PRESS_EVENT_H_ +#define KIS_BUTTON_PRESS_EVENT_H_ + +#include "kis_button_event.h" + +class KisButtonPressEvent : public KisButtonEvent { + typedef KisButtonEvent super; +public: + KisButtonPressEvent() {} + KisButtonPressEvent(KisInputDevice device, const KisPoint& pos, const KisPoint& globalPos, double pressure, double xTilt, double yTilt, TQt::ButtonState button, TQt::ButtonState state) : super(ButtonPressEvent, device, pos, globalPos, pressure, xTilt, yTilt, button, state) {} +}; + +#endif // KIS_BUTTON_PRESS_EVENT_H_ + diff --git a/chalk/ui/kis_button_release_event.h b/chalk/ui/kis_button_release_event.h new file mode 100644 index 00000000..f6da4dfd --- /dev/null +++ b/chalk/ui/kis_button_release_event.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2004 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_BUTTON_RELEASE_EVENT_H_ +#define KIS_BUTTON_RELEASE_EVENT_H_ + +#include "kis_button_event.h" + +class KisButtonReleaseEvent : public KisButtonEvent { + typedef KisButtonEvent super; +public: + KisButtonReleaseEvent() {} + KisButtonReleaseEvent(KisInputDevice device, const KisPoint& pos, const KisPoint& globalPos, double pressure, double xTilt, double yTilt, TQt::ButtonState button, TQt::ButtonState state) : super(ButtonReleaseEvent, device, pos, globalPos, pressure, xTilt, yTilt, button, state) {} +}; + +#endif // KIS_BUTTON_RELEASE_EVENT_H_ + diff --git a/chalk/ui/kis_canvas.cc b/chalk/ui/kis_canvas.cc new file mode 100644 index 00000000..01ca372e --- /dev/null +++ b/chalk/ui/kis_canvas.cc @@ -0,0 +1,1355 @@ +/* + * Copyright (c) 1999 Matthias Elter <me@kde.org> + * Copyright (c) 2004-2006 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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.g + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + + Some of the X11-specific event handling code is based upon code from + src/kernel/qapplication_x11.cpp from the TQt GUI Toolkit and is subject + to the following license and copyright: + + **************************************************************************** +** +** +** Implementation of X11 startup routines and event handling +** +** Created : 931029 +** +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. +** +** This file is part of the kernel module of the TQt GUI Toolkit. +** +** This file may be distributed under the terms of the Q Public License +** as defined by Trolltech AS of Norway and appearing in the file +** LICENSE.TQPL included in the packaging of this file. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** Licensees holding valid TQt Enterprise Edition or TQt Professional Edition +** licenses for Unix/X11 may use this file in accordance with the TQt Commercial +** License Agreement provided with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about TQt Commercial License Agreements. +** See http://www.trolltech.com/qpl/ for TQPL licensing information. +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include <tqcursor.h> + +#include "kis_canvas.h" +#include "kis_cursor.h" +#include "kis_move_event.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_double_click_event.h" +#include "kis_config.h" +#include "kis_qpaintdevice_canvas.h" +#include "kis_opengl_canvas.h" +#include "kis_config.h" +#include "kis_input_device.h" +#include "fixx11h.h" + +#ifdef Q_WS_X11 + +#include <tqdesktopwidget.h> +#include <tqapplication.h> + +#include <X11/keysym.h> + +bool KisCanvasWidget::X11SupportInitialised = false; +long KisCanvasWidget::X11AltMask = 0; +long KisCanvasWidget::X11MetaMask = 0; + +#if defined(EXTENDED_X11_TABLET_SUPPORT) + +int KisCanvasWidget::X11DeviceMotionNotifyEvent = -1; +int KisCanvasWidget::X11DeviceButtonPressEvent = -1; +int KisCanvasWidget::X11DeviceButtonReleaseEvent = -1; +int KisCanvasWidget::X11ProximityInEvent = -1; +int KisCanvasWidget::X11ProximityOutEvent = -1; + +//X11XIDTabletDeviceMap KisCanvasWidget::X11TabletDeviceMap; +std::map<XID, KisCanvasWidget::X11TabletDevice> KisCanvasWidget::X11TabletDeviceMap; + +#endif // EXTENDED_X11_TABLET_SUPPORT + +#endif // Q_WS_X11 + +KisCanvasWidget::KisCanvasWidget() +{ + m_enableMoveEventCompressionHint = false; + m_lastPressure = 0; + +#ifdef Q_WS_X11 + if (!X11SupportInitialised) { + initX11Support(); + } + + m_lastRootX = -1; + m_lastRootY = -1; +#endif +} + +KisCanvasWidget::~KisCanvasWidget() +{ +} + +void KisCanvasWidget::widgetGotPaintEvent(TQPaintEvent *e) +{ + emit sigGotPaintEvent(e); +} + +void KisCanvasWidget::widgetGotMousePressEvent(TQMouseEvent *e) +{ + KisButtonPressEvent ke(KisInputDevice::mouse(), KisPoint(e->pos()), KisPoint(e->globalPos()), PRESSURE_DEFAULT, 0, 0, e->button(), e->state()); + buttonPressEvent(&ke); +} + +void KisCanvasWidget::widgetGotMouseReleaseEvent(TQMouseEvent *e) +{ + KisButtonReleaseEvent ke(KisInputDevice::mouse(), KisPoint(e->pos()), KisPoint(e->globalPos()), PRESSURE_DEFAULT, 0, 0, e->button(), e->state()); + buttonReleaseEvent(&ke); +} + +void KisCanvasWidget::widgetGotMouseDoubleClickEvent(TQMouseEvent *e) +{ + KisDoubleClickEvent ke(KisInputDevice::mouse(), KisPoint(e->pos()), KisPoint(e->globalPos()), PRESSURE_DEFAULT, 0, 0, e->button(), e->state()); + doubleClickEvent(&ke); +} + +void KisCanvasWidget::widgetGotMouseMoveEvent(TQMouseEvent *e) +{ + KisMoveEvent ke(KisInputDevice::mouse(), KisPoint(e->pos()), KisPoint(e->globalPos()), PRESSURE_DEFAULT, 0, 0, e->state()); + moveEvent(&ke); +} + +void KisCanvasWidget::widgetGotTabletEvent(TQTabletEvent *e) +{ + KisInputDevice device; + + switch (e->device()) { + default: + case TQTabletEvent::NoDevice: + case TQTabletEvent::Stylus: + device = KisInputDevice::stylus(); + break; + case TQTabletEvent::Puck: + device = KisInputDevice::puck(); + break; + case TQTabletEvent::Eraser: + device = KisInputDevice::eraser(); + break; + } + + double pressure = e->pressure() / 255.0; + + if (e->type() == TQEvent::TabletPress) { + KisButtonPressEvent ke(device, KisPoint(e->pos()), KisPoint(e->globalPos()), pressure, e->xTilt(), e->yTilt(), Qt::LeftButton, Qt::NoButton); + translateTabletEvent(&ke); + } + else + if (e->type() == TQEvent::TabletRelease) { + KisButtonReleaseEvent ke(device, KisPoint(e->pos()), KisPoint(e->globalPos()), pressure, e->xTilt(), e->yTilt(), Qt::LeftButton, Qt::NoButton); + translateTabletEvent(&ke); + } + else { + KisMoveEvent ke(device, KisPoint(e->pos()), KisPoint(e->globalPos()), pressure, e->xTilt(), e->yTilt(), Qt::NoButton); + translateTabletEvent(&ke); +#ifdef Q_WS_X11 + // Fix the problem that when you change from using a tablet device to the mouse, + // the first mouse button event is not recognised. This is because we handle + // X11 core mouse move events directly so TQt does not get to see them. This breaks + // the tablet event accept/ignore mechanism, causing TQt to consume the first + // mouse button event it sees, instead of a mouse move. 'Ignoring' tablet move events + // stops TQt from stealing the next mouse button event. This does not affect the + // tablet aware tools as they do not care about mouse moves while the tablet device is + // drawing. + e->ignore(); +#endif + } +} + +void KisCanvasWidget::widgetGotEnterEvent(TQEvent *e) +{ + emit sigGotEnterEvent(e); +} + +void KisCanvasWidget::widgetGotLeaveEvent(TQEvent *e) +{ + emit sigGotLeaveEvent(e); +} + +void KisCanvasWidget::widgetGotWheelEvent(TQWheelEvent *e) +{ + emit sigGotMouseWheelEvent(e); +} + +void KisCanvasWidget::widgetGotKeyPressEvent(TQKeyEvent *e) +{ + emit sigGotKeyPressEvent(e); +} + +void KisCanvasWidget::widgetGotKeyReleaseEvent(TQKeyEvent *e) +{ + emit sigGotKeyReleaseEvent(e); +} + +void KisCanvasWidget::widgetGotDragEnterEvent(TQDragEnterEvent *e) +{ + emit sigGotDragEnterEvent(e); +} + +void KisCanvasWidget::widgetGotDropEvent(TQDropEvent *e) +{ + emit sigGotDropEvent(e); +} + +void KisCanvasWidget::moveEvent(KisMoveEvent *e) +{ + emit sigGotMoveEvent(e); +} + +void KisCanvasWidget::buttonPressEvent(KisButtonPressEvent *e) +{ + TQWidget *widget = dynamic_cast<TQWidget *>(this); + Q_ASSERT(widget != 0); + + if (widget) { + widget->setFocus(); + } + + emit sigGotButtonPressEvent(e); +} + +void KisCanvasWidget::buttonReleaseEvent(KisButtonReleaseEvent *e) +{ + emit sigGotButtonReleaseEvent(e); +} + +void KisCanvasWidget::doubleClickEvent(KisDoubleClickEvent *e) +{ + emit sigGotDoubleClickEvent(e); +} + +void KisCanvasWidget::translateTabletEvent(KisEvent *e) +{ + bool checkThresholdOnly = false; + + if (e->type() == KisEvent::ButtonPressEvent || e->type() == KisEvent::ButtonReleaseEvent) { + KisButtonEvent *b = static_cast<KisButtonEvent *>(e); + + if (b->button() == Qt::MidButton || b->button() == Qt::RightButton) { + + if (e->type() == KisEvent::ButtonPressEvent) { + buttonPressEvent(static_cast<KisButtonPressEvent *>(e)); + } else { + buttonReleaseEvent(static_cast<KisButtonReleaseEvent *>(e)); + } + + checkThresholdOnly = true; + } + } + + // Use pressure threshold to detect 'left button' press/release + if (e->pressure() >= PRESSURE_THRESHOLD && m_lastPressure < PRESSURE_THRESHOLD) { + KisButtonPressEvent ke(e->device(), e->pos(), e->globalPos(), e->pressure(), e->xTilt(), e->yTilt(), Qt::LeftButton, e->state()); + buttonPressEvent(&ke); + } else if (e->pressure() < PRESSURE_THRESHOLD && m_lastPressure >= PRESSURE_THRESHOLD) { + KisButtonReleaseEvent ke(e->device(), e->pos(), e->globalPos(), e->pressure(), e->xTilt(), e->yTilt(), Qt::LeftButton, e->state()); + buttonReleaseEvent(&ke); + } else { + if (!checkThresholdOnly) { + KisMoveEvent ke(e->device(), e->pos(), e->globalPos(), e->pressure(), e->xTilt(), e->yTilt(), e->state()); + moveEvent(&ke); + } + } + + m_lastPressure = e->pressure(); +} + +#ifdef Q_WS_X11 + +void KisCanvasWidget::initX11Support() +{ + if (X11SupportInitialised) + { + return; + } + + X11SupportInitialised = true; + + Display *x11Display = TQApplication::desktop()->x11Display(); + + // Look at the modifier mapping and get the correct tqmasks for alt/meta + XModifierKeymap *map = XGetModifierMapping(x11Display); + + if (map) { + int mapIndex = 0; + + for (int tqmaskIndex = 0; tqmaskIndex < 8; tqmaskIndex++) { + for (int i = 0; i < map->max_keypermod; i++) { + if (map->modifiermap[mapIndex]) { + + KeySym sym = XKeycodeToKeysym(x11Display, map->modifiermap[mapIndex], 0); + + if (X11AltMask == 0 && (sym == XK_Alt_L || sym == XK_Alt_R)) { + X11AltMask = 1 << tqmaskIndex; + } + if (X11MetaMask == 0 && (sym == XK_Meta_L || sym == XK_Meta_R)) { + X11MetaMask = 1 << tqmaskIndex; + } + } + + mapIndex++; + } + } + + XFreeModifiermap(map); + } + else { + // Assume defaults + X11AltMask = Mod1Mask; + X11MetaMask = Mod4Mask; + } + +#if defined(EXTENDED_X11_TABLET_SUPPORT) + + int numDevices = 0; + const XDeviceInfo *devices = XListInputDevices(x11Display, &numDevices); + + if (devices != NULL) { + XID lastStylusSeen = 0; + XID lastEraserSeen = 0; + bool foundStylus = false; + bool foundEraser = false; + + for (int i = 0; i < numDevices; i++) { + + const XDeviceInfo *device = devices + i; + X11TabletDevice tabletDevice(device); + + if (tabletDevice.mightBeTabletDevice()) { + + tabletDevice.readSettingsFromConfig(); + + TQString lowerCaseName = tabletDevice.name().lower(); + + // Find the devices that TQt will use as its stylus and eraser devices. + if (!foundStylus || !foundEraser) { + if (lowerCaseName.startsWith("stylus") || lowerCaseName.startsWith("pen")) { + lastStylusSeen = device->id; + foundStylus = true; + } + else if (lowerCaseName.startsWith("eraser")) { + lastEraserSeen = device->id; + foundEraser = true; + } + } + + X11TabletDeviceMap[device->id] = tabletDevice; + + // Event types are device-independent. Store any + // the device supports. + if (tabletDevice.buttonPressEvent() >= 0) { + X11DeviceButtonPressEvent = tabletDevice.buttonPressEvent(); + } + if (tabletDevice.buttonReleaseEvent() >= 0) { + X11DeviceButtonReleaseEvent = tabletDevice.buttonReleaseEvent(); + } + if (tabletDevice.motionNotifyEvent() >= 0) { + X11DeviceMotionNotifyEvent = tabletDevice.motionNotifyEvent(); + } + if (tabletDevice.proximityInEvent() >= 0) { + X11ProximityInEvent = tabletDevice.proximityInEvent(); + } + if (tabletDevice.proximityOutEvent() >= 0) { + X11ProximityOutEvent = tabletDevice.proximityOutEvent(); + } + } + } + + // Allocate input devices. + for (X11XIDTabletDeviceMap::iterator it = X11TabletDeviceMap.begin(); it != X11TabletDeviceMap.end(); ++it) { + + X11TabletDevice& tabletDevice = (*it).second; + + if (foundStylus && tabletDevice.id() == lastStylusSeen) { + tabletDevice.setInputDevice(KisInputDevice::stylus()); + } else if (foundEraser && tabletDevice.id() == lastEraserSeen) { + tabletDevice.setInputDevice(KisInputDevice::eraser()); + } else { + tabletDevice.setInputDevice(KisInputDevice::allocateInputDevice()); + } + } + + XFreeDeviceList(const_cast<XDeviceInfo *>(devices)); + } +#endif // EXTENDED_X11_TABLET_SUPPORT +} + +TQt::ButtonState KisCanvasWidget::translateX11ButtonState(int state) +{ + int buttonState = 0; + + if (state & Button1Mask) + buttonState |= Qt::LeftButton; + if (state & Button2Mask) + buttonState |= Qt::MidButton; + if (state & Button3Mask) + buttonState |= Qt::RightButton; + if (state & ShiftMask) + buttonState |= TQt::ShiftButton; + if (state & ControlMask) + buttonState |= TQt::ControlButton; + if (state & X11AltMask) + buttonState |= TQt::AltButton; + if (state & X11MetaMask) + buttonState |= TQt::MetaButton; + + return static_cast<TQt::ButtonState>(buttonState); +} + +TQt::ButtonState KisCanvasWidget::translateX11Button(unsigned int X11Button) +{ + TQt::ButtonState qtButton; + + switch (X11Button) { + case Button1: + qtButton = Qt::LeftButton; + break; + case Button2: + qtButton = Qt::MidButton; + break; + case Button3: + qtButton = Qt::RightButton; + break; + default: + qtButton = Qt::NoButton; + } + + return qtButton; +} + +#if defined(EXTENDED_X11_TABLET_SUPPORT) + +KisCanvasWidget::X11TabletDevice::X11TabletDevice() +{ + m_mightBeTabletDevice = false; + m_inputDevice = KisInputDevice::unknown(); + m_enabled = false; + m_xAxis = NoAxis; + m_yAxis = NoAxis; + m_pressureAxis = NoAxis; + m_xTiltAxis = NoAxis; + m_yTiltAxis = NoAxis; + m_wheelAxis = NoAxis; + m_toolIDAxis = NoAxis; + m_serialNumberAxis = NoAxis; + m_buttonPressEvent = -1; + m_buttonReleaseEvent = -1; + m_motionNotifyEvent = -1; + m_proximityInEvent = -1; + m_proximityOutEvent = -1; +} + +KisCanvasWidget::X11TabletDevice::X11TabletDevice(const XDeviceInfo *deviceInfo) +{ + m_mightBeTabletDevice = false; + m_inputDevice = KisInputDevice::unknown(); + m_enabled = false; + m_xAxis = NoAxis; + m_yAxis = NoAxis; + m_pressureAxis = NoAxis; + m_xTiltAxis = NoAxis; + m_yTiltAxis = NoAxis; + m_wheelAxis = NoAxis; + m_toolIDAxis = NoAxis; + m_serialNumberAxis = NoAxis; + + m_deviceId = deviceInfo->id; + m_name = deviceInfo->name; + + // Get the ranges of the valuators + XAnyClassPtr classInfo = const_cast<XAnyClassPtr>(deviceInfo->inputclassinfo); + + for (int i = 0; i < deviceInfo->num_classes; i++) { + + if (classInfo->c_class == ValuatorClass) { + + const XValuatorInfo *valuatorInfo = reinterpret_cast<const XValuatorInfo *>(classInfo); + + // Need at least x, y, and pressure. + + if (valuatorInfo->num_axes >= 3) { + + for (unsigned int axis = 0; axis < valuatorInfo->num_axes; axis++) { + m_axisInfo.append(valuatorInfo->axes[axis]); + } + + m_mightBeTabletDevice = true; + } + } + + classInfo = reinterpret_cast<XAnyClassPtr>(reinterpret_cast<char *>(classInfo) + classInfo->length); + } + + // Determine the event types it supports. We're only interested in + // buttons and motion at the moment. + m_buttonPressEvent = -1; + m_buttonReleaseEvent = -1; + m_motionNotifyEvent = -1; + m_proximityInEvent = -1; + m_proximityOutEvent = -1; + + m_XDevice = XOpenDevice(TQApplication::desktop()->x11Display(), m_deviceId); + + if (m_XDevice != NULL) { + for (int i = 0; i < m_XDevice->num_classes; i++) { + + XEventClass eventClass; + + if (m_XDevice->classes[i].input_class == ButtonClass) { + DeviceButtonPress(m_XDevice, m_buttonPressEvent, eventClass); + m_eventClassList.append(eventClass); + + DeviceButtonRelease(m_XDevice, m_buttonReleaseEvent, eventClass); + m_eventClassList.append(eventClass); + } + else + if (m_XDevice->classes[i].input_class == ValuatorClass) { + DeviceMotionNotify(m_XDevice, m_motionNotifyEvent, eventClass); + m_eventClassList.append(eventClass); + } + else + if (m_XDevice->classes[i].input_class == ProximityClass) { + ProximityIn(m_XDevice, m_proximityInEvent, eventClass); + m_eventClassList.append(eventClass); + + ProximityOut(m_XDevice, m_proximityOutEvent, eventClass); + m_eventClassList.append(eventClass); + } + } + + // Note: We don't XCloseXDevice() since TQt will have already opened + // it, and only one XCloseDevice() call closes it for all opens. + } + + if (m_buttonPressEvent == -1 || m_buttonReleaseEvent == -1 || m_motionNotifyEvent == -1) { + m_mightBeTabletDevice = false; + } +} + +void KisCanvasWidget::X11TabletDevice::setEnabled(bool enabled) +{ + m_enabled = enabled; +} + +bool KisCanvasWidget::X11TabletDevice::enabled() const +{ + return m_enabled; +} + +TQ_INT32 KisCanvasWidget::X11TabletDevice::numAxes() const +{ + return m_axisInfo.count(); +} + +void KisCanvasWidget::X11TabletDevice::setXAxis(TQ_INT32 axis) +{ + m_xAxis = axis; +} + +void KisCanvasWidget::X11TabletDevice::setYAxis(TQ_INT32 axis) +{ + m_yAxis = axis; +} + +void KisCanvasWidget::X11TabletDevice::setPressureAxis(TQ_INT32 axis) +{ + m_pressureAxis = axis; +} + +void KisCanvasWidget::X11TabletDevice::setXTiltAxis(TQ_INT32 axis) +{ + m_xTiltAxis = axis; +} + +void KisCanvasWidget::X11TabletDevice::setYTiltAxis(TQ_INT32 axis) +{ + m_yTiltAxis = axis; +} + +void KisCanvasWidget::X11TabletDevice::setWheelAxis(TQ_INT32 axis) +{ + m_wheelAxis = axis; +} + +void KisCanvasWidget::X11TabletDevice::setToolIDAxis(TQ_INT32 axis) +{ + m_toolIDAxis = axis; +} + +void KisCanvasWidget::X11TabletDevice::setSerialNumberAxis(TQ_INT32 axis) +{ + m_serialNumberAxis = axis; +} + +TQ_INT32 KisCanvasWidget::X11TabletDevice::xAxis() const +{ + return m_xAxis; +} + +TQ_INT32 KisCanvasWidget::X11TabletDevice::yAxis() const +{ + return m_yAxis; +} + +TQ_INT32 KisCanvasWidget::X11TabletDevice::pressureAxis() const +{ + return m_pressureAxis; +} + +TQ_INT32 KisCanvasWidget::X11TabletDevice::xTiltAxis() const +{ + return m_xTiltAxis; +} + +TQ_INT32 KisCanvasWidget::X11TabletDevice::yTiltAxis() const +{ + return m_yTiltAxis; +} + +TQ_INT32 KisCanvasWidget::X11TabletDevice::wheelAxis() const +{ + return m_wheelAxis; +} + +TQ_INT32 KisCanvasWidget::X11TabletDevice::toolIDAxis() const +{ + return m_toolIDAxis; +} + +TQ_INT32 KisCanvasWidget::X11TabletDevice::serialNumberAxis() const +{ + return m_serialNumberAxis; +} + +void KisCanvasWidget::X11TabletDevice::readSettingsFromConfig() +{ + KisConfig cfg; + + m_enabled = cfg.tabletDeviceEnabled(m_name); + + m_xAxis = cfg.tabletDeviceAxis(m_name, "XAxis", DefaultAxis); + m_yAxis = cfg.tabletDeviceAxis(m_name, "YAxis", DefaultAxis); + m_pressureAxis = cfg.tabletDeviceAxis(m_name, "PressureAxis", DefaultAxis); + m_xTiltAxis = cfg.tabletDeviceAxis(m_name, "XTiltAxis", DefaultAxis); + m_yTiltAxis = cfg.tabletDeviceAxis(m_name, "YTiltAxis", DefaultAxis); + m_wheelAxis = cfg.tabletDeviceAxis(m_name, "WheelAxis", DefaultAxis); + m_toolIDAxis = cfg.tabletDeviceAxis(m_name, "ToolIDAxis", DefaultAxis); + m_serialNumberAxis = cfg.tabletDeviceAxis(m_name, "SerialNumberAxis", DefaultAxis); + + if (!m_enabled && m_xAxis == DefaultAxis && m_yAxis == DefaultAxis && m_pressureAxis == DefaultAxis && + m_xTiltAxis == DefaultAxis && m_yTiltAxis == DefaultAxis && m_wheelAxis == DefaultAxis && + m_toolIDAxis == DefaultAxis && m_serialNumberAxis == DefaultAxis) { + // This is the first time this device has been seen. Set up default values, assuming + // it's a Wacom pad. + m_xAxis = 0; + m_yAxis = 1; + m_pressureAxis = 2; + + if (m_axisInfo.count() >= 4) { + m_xTiltAxis = 3; + } else { + m_xTiltAxis = NoAxis; + } + + if (m_axisInfo.count() >= 5) { + m_yTiltAxis = 4; + } else { + m_yTiltAxis = NoAxis; + } + + if (m_axisInfo.count() >= 6) { + m_wheelAxis = 5; + } else { + m_wheelAxis = NoAxis; + } + + // Available since driver version 0.7.2. + if (m_axisInfo.count() >= 7) { + m_toolIDAxis = 6; + } else { + m_toolIDAxis = NoAxis; + } + + if (m_axisInfo.count() >= 8) { + m_serialNumberAxis = 7; + } else { + m_serialNumberAxis = NoAxis; + } + } +} + +void KisCanvasWidget::X11TabletDevice::writeSettingsToConfig() +{ + KisConfig cfg; + + cfg.setTabletDeviceEnabled(m_name, m_enabled); + + cfg.setTabletDeviceAxis(m_name, "XAxis", m_xAxis); + cfg.setTabletDeviceAxis(m_name, "YAxis", m_yAxis); + cfg.setTabletDeviceAxis(m_name, "PressureAxis", m_pressureAxis); + cfg.setTabletDeviceAxis(m_name, "XTiltAxis", m_xTiltAxis); + cfg.setTabletDeviceAxis(m_name, "YTiltAxis", m_yTiltAxis); + cfg.setTabletDeviceAxis(m_name, "WheelAxis", m_wheelAxis); + cfg.setTabletDeviceAxis(m_name, "ToolIDAxis", m_toolIDAxis); + cfg.setTabletDeviceAxis(m_name, "SerialNumberAxis", m_serialNumberAxis); +} + +void KisCanvasWidget::X11TabletDevice::enableEvents(TQWidget *widget) const +{ + if (!m_eventClassList.isEmpty()) { + int result = XSelectExtensionEvent(TQT_TQPAINTDEVICE(widget)->x11AppDisplay(), widget->handle(), + const_cast<XEventClass*>(&m_eventClassList[0]), + m_eventClassList.count()); + + if (result != Success) { + kdDebug(41001) << "Failed to select extension events for " << m_name << endl; + } + } +} + +double KisCanvasWidget::X11TabletDevice::translateAxisValue(int value, const XAxisInfo& axisInfo) const +{ + int axisRange = axisInfo.max_value - axisInfo.min_value; + double translatedValue = 0; + + if (axisRange != 0) { + translatedValue = (static_cast<double>(value) - axisInfo.min_value) / axisRange; + if (axisInfo.min_value < 0) { + translatedValue -= 0.5; + } + } + + return translatedValue; +} + +KisCanvasWidget::X11TabletDevice::State::State(const KisPoint& pos, double pressure, const KisVector2D& tilt, double wheel, + TQ_UINT32 toolID, TQ_UINT32 serialNumber) + : m_pos(pos), + m_pressure(pressure), + m_tilt(tilt), + m_wheel(wheel), + m_toolID(toolID), + m_serialNumber(serialNumber) +{ +} + +KisCanvasWidget::X11TabletDevice::State KisCanvasWidget::X11TabletDevice::translateAxisData(const int *axisData) const +{ + KisPoint pos(0, 0); + + if (m_xAxis != NoAxis && m_yAxis != NoAxis) { + pos = KisPoint(translateAxisValue(axisData[m_xAxis], m_axisInfo[m_xAxis]), + translateAxisValue(axisData[m_yAxis], m_axisInfo[m_yAxis])); + } + + double pressure = PRESSURE_DEFAULT; + + if (m_pressureAxis != NoAxis) { + pressure = translateAxisValue(axisData[m_pressureAxis], m_axisInfo[m_pressureAxis]); + } + + KisVector2D tilt = KisVector2D(0, 0); + TQ_UINT32 toolID = 0; + TQ_UINT32 serialNumber = 0; + + if (m_xTiltAxis != NoAxis) { + // Latest wacom driver returns the tool id and serial number in + // the upper 16 bits of the x and y tilts and wheel. + int xTiltAxisValue = (TQ_INT16)(axisData[m_xTiltAxis] & 0xffff); + toolID = ((TQ_UINT32)axisData[m_xTiltAxis] >> 16) & 0xffff; + + tilt.setX(translateAxisValue(xTiltAxisValue, m_axisInfo[m_xTiltAxis])); + } + + if (m_yTiltAxis != NoAxis) { + int yTiltAxisValue = (TQ_INT16)(axisData[m_yTiltAxis] & 0xffff); + serialNumber = (TQ_UINT32)axisData[m_yTiltAxis] & 0xffff0000; + + tilt.setY(translateAxisValue(yTiltAxisValue, m_axisInfo[m_yTiltAxis])); + } + + double wheel = 0; + + if (m_wheelAxis != NoAxis) { + int wheelAxisValue = (TQ_INT16)(axisData[m_wheelAxis] & 0xffff); + serialNumber |= ((TQ_UINT32)axisData[m_wheelAxis] >> 16) & 0xffff; + + wheel = translateAxisValue(wheelAxisValue, m_axisInfo[m_wheelAxis]); + } + + //TQString ids; + //ids.sprintf("Tool ID: %8x Serial Number: %8x", toolID, serialNumber); + + return State(pos, pressure, tilt, wheel, toolID, serialNumber); +} + +KisCanvasWidget::X11XIDTabletDeviceMap& KisCanvasWidget::tabletDeviceMap() +{ + return X11TabletDeviceMap; +} + +void KisCanvasWidget::selectTabletDeviceEvents(TQWidget *widget) +{ + for (X11XIDTabletDeviceMap::const_iterator it = X11TabletDeviceMap.begin(); it != X11TabletDeviceMap.end(); ++it) { + + const X11TabletDevice& device = (*it).second; + + if (device.enabled()) { + device.enableEvents(widget); + } + } +} + +#endif // EXTENDED_X11_TABLET_SUPPORT + +bool KisCanvasWidget::x11Event(XEvent *event, Display *x11Display, WId winId, TQPoint widgetOriginPos) +{ + if (event->type == MotionNotify) { + // Mouse move + if (!m_enableMoveEventCompressionHint) { + + XMotionEvent motion = event->xmotion; + TQPoint globalPos(motion.x_root, motion.y_root); + + if (globalPos.x() != m_lastRootX || globalPos.y() != m_lastRootY) { + + int state = translateX11ButtonState(motion.state); + TQPoint pos(motion.x, motion.y); + TQMouseEvent e(TQEvent::MouseMove, pos, globalPos, Qt::NoButton, state); + + widgetGotMouseMoveEvent(&e); + } + + m_lastRootX = globalPos.x(); + m_lastRootY = globalPos.y(); + + return true; + } + else { + return false; + } + } + else +#if defined(EXTENDED_X11_TABLET_SUPPORT) + if (event->type == X11DeviceMotionNotifyEvent || event->type == X11DeviceButtonPressEvent || event->type == X11DeviceButtonReleaseEvent) { + // Tablet event. + int deviceId; + const int *axisData; + TQt::ButtonState button; + TQt::ButtonState buttonState; + + if (event->type == X11DeviceMotionNotifyEvent) { + // Tablet move + const XDeviceMotionEvent *motion = reinterpret_cast<const XDeviceMotionEvent *>(event); + XEvent mouseEvent; + + // Look for an accompanying core event. + if (XCheckTypedWindowEvent(x11Display, winId, MotionNotify, &mouseEvent)) { + if (motion->time == mouseEvent.xmotion.time) { + // Do nothing + } else { + XPutBackEvent(x11Display, &mouseEvent); + } + } + + if (m_enableMoveEventCompressionHint) { + while (true) { + // Look for another motion notify in the queue and skip + // to that if found. + if (!XCheckTypedWindowEvent(x11Display, winId, X11DeviceMotionNotifyEvent, &mouseEvent)) { + break; + } + + motion = reinterpret_cast<const XDeviceMotionEvent *>(&mouseEvent); + + XEvent coreMotionEvent; + + // Look for an accompanying core event. + if (!XCheckTypedWindowEvent(x11Display, winId, MotionNotify, &coreMotionEvent)) { + // Do nothing + } + } + } + + deviceId = motion->deviceid; + axisData = motion->axis_data; + button = Qt::NoButton; + buttonState = translateX11ButtonState(motion->state); + } + else + if (event->type == X11DeviceButtonPressEvent) { + // Tablet button press + const XDeviceButtonPressedEvent *buttonPressed = reinterpret_cast<const XDeviceButtonPressedEvent *>(event); + deviceId = buttonPressed->deviceid; + axisData = buttonPressed->axis_data; + button = translateX11Button(buttonPressed->button); + buttonState = translateX11ButtonState(buttonPressed->state); + + if (TQApplication::activePopupWidget() == 0) { + XEvent mouseEvent; + + // Look for and swallow an accompanying core event, but only if there's + // no active popup, as that needs to see it. + if (XCheckTypedWindowEvent(x11Display, winId, ButtonPress, &mouseEvent)) { + if (buttonPressed->time == mouseEvent.xbutton.time) { + // Do nothing + } + else { + XPutBackEvent(x11Display, &mouseEvent); + } + } + } + } + else { + // Tablet button release + const XDeviceButtonReleasedEvent *buttonReleased = reinterpret_cast<const XDeviceButtonReleasedEvent *>(event); + deviceId = buttonReleased->deviceid; + axisData = buttonReleased->axis_data; + button = translateX11Button(buttonReleased->button); + buttonState = translateX11ButtonState(buttonReleased->state); + + if (TQApplication::activePopupWidget() == 0) { + XEvent mouseEvent; + + // Look for and swallow an accompanying core event, but only if there's + // no active popup, as that needs to see it. + if (XCheckTypedWindowEvent(x11Display, winId, ButtonRelease, &mouseEvent)) { + if (buttonReleased->time == mouseEvent.xbutton.time) { + // Do nothing + } + else { + XPutBackEvent(x11Display, &mouseEvent); + } + } + } + } + + X11XIDTabletDeviceMap::const_iterator it = X11TabletDeviceMap.find(deviceId); + + if (it != X11TabletDeviceMap.end()) { + + const X11TabletDevice& tabletDevice = (*it).second; + + if (tabletDevice.enabled()) { + X11TabletDevice::State deviceState = tabletDevice.translateAxisData(axisData); + + // Map normalised position coordinates to screen coordinates + TQDesktopWidget *desktop = TQApplication::desktop(); + KisPoint globalPos(deviceState.pos().x() * desktop->width(), deviceState.pos().y() * desktop->height()); + // Convert screen coordinates to widget coordinates + KisPoint pos = globalPos - KoPoint( widgetOriginPos ); + + // Map tilt to -60 - +60 degrees + KisVector2D tilt(deviceState.tilt().x() * 60, deviceState.tilt().y() * 60); + + if (event->type == X11DeviceMotionNotifyEvent) { + KisMoveEvent e(tabletDevice.inputDevice(), pos, globalPos, deviceState.pressure(), tilt.x(), tilt.y(), buttonState); + translateTabletEvent(&e); + } + else + if (event->type == X11DeviceButtonPressEvent) { + KisButtonPressEvent e(tabletDevice.inputDevice(), pos, globalPos, deviceState.pressure(), tilt.x(), tilt.y(), button, buttonState); + translateTabletEvent(&e); + } + else { + KisButtonReleaseEvent e(tabletDevice.inputDevice(), pos, globalPos, deviceState.pressure(), tilt.x(), tilt.y(), button, buttonState); + translateTabletEvent(&e); + } + } + + // Consume the event even if the device is disabled otherwise TQt will + // process it and send a TQTabletEvent. + return true; + } + else { + return false; + } + } + else +#endif // EXTENDED_X11_TABLET_SUPPORT + { + return false; + } +} + +#if defined(EXTENDED_X11_TABLET_SUPPORT) + +KisInputDevice KisCanvasWidget::findActiveInputDevice() +{ + X11XIDTabletDeviceMap::const_iterator it; + + for (it = X11TabletDeviceMap.begin(); it != X11TabletDeviceMap.end(); ++it) { + const X11TabletDevice& tabletDevice = (*it).second; + + XDeviceState *deviceState = XQueryDeviceState(TQApplication::desktop()->x11Display(), + tabletDevice.xDevice()); + + // If your the laptop sleeps, and you remove the mouse from the usb + // port, then on wake-up Chalk can crash because the above call will + // return 0. + if (!deviceState) continue; + + const XInputClass *inputClass = deviceState->data; + bool deviceIsInProximity = false; + + for (int i = 0; i < deviceState->num_classes; i++) { + + if (inputClass->c_class == ValuatorClass) { + + const XValuatorState *valuatorState = reinterpret_cast<const XValuatorState *>(inputClass); + + if ((valuatorState->mode & ProximityState) == InProximity) { + deviceIsInProximity = true; + break; + } + } + + inputClass = reinterpret_cast<const XInputClass *>(reinterpret_cast<const char *>(inputClass) + inputClass->length); + } + + XFreeDeviceState(deviceState); + + if (deviceIsInProximity && tabletDevice.enabled()) { + return tabletDevice.inputDevice(); + } + } + + return KisInputDevice::mouse(); +} + +#endif // EXTENDED_X11_TABLET_SUPPORT + + +#endif // Q_WS_X11 + +/*************************************************************************/ + +#define TQPAINTDEVICE_CANVAS_WIDGET false +#define OPENGL_CANVAS_WIDGET true + +KisCanvas::KisCanvas(TQWidget *tqparent, const char *name) +{ + m_parent = tqparent; + m_name = name; + m_enableMoveEventCompressionHint = false; + m_canvasWidget = 0; + m_useOpenGL = false; + createCanvasWidget(TQPAINTDEVICE_CANVAS_WIDGET); +} + +KisCanvas::~KisCanvas() +{ + delete m_canvasWidget; +} + +#ifdef HAVE_GL +void KisCanvas::createCanvasWidget(bool useOpenGL, TQGLWidget *sharedContextWidget) +#else +void KisCanvas::createCanvasWidget(bool useOpenGL) +#endif +{ + delete m_canvasWidget; + +#ifndef HAVE_GL + useOpenGL = false; +#else + if (useOpenGL && !TQGLFormat::hasOpenGL()) { + kdDebug(41001) << "Tried to create OpenGL widget when system doesn't have OpenGL\n"; + useOpenGL = false; + } + + if (useOpenGL) { + m_canvasWidget = new KisOpenGLCanvasWidget(m_parent, m_name.latin1(), sharedContextWidget); + } else +#endif + { + m_canvasWidget = new KisTQPaintDeviceCanvasWidget(m_parent, m_name.latin1()); + } + + m_useOpenGL = useOpenGL; + + Q_CHECK_PTR(m_canvasWidget); + TQWidget *widget = dynamic_cast<TQWidget *>(m_canvasWidget); + + widget->setBackgroundMode(TQWidget::NoBackground); + widget->setMouseTracking(true); + widget->setAcceptDrops(true); + m_canvasWidget->enableMoveEventCompressionHint(m_enableMoveEventCompressionHint); + +#if defined(EXTENDED_X11_TABLET_SUPPORT) + selectTabletDeviceEvents(); +#endif + + connect(m_canvasWidget, TQT_SIGNAL(sigGotPaintEvent(TQPaintEvent *)), TQT_SIGNAL(sigGotPaintEvent(TQPaintEvent *))); + connect(m_canvasWidget, TQT_SIGNAL(sigGotEnterEvent(TQEvent*)), TQT_SIGNAL(sigGotEnterEvent(TQEvent*))); + connect(m_canvasWidget, TQT_SIGNAL(sigGotLeaveEvent(TQEvent*)), TQT_SIGNAL(sigGotLeaveEvent(TQEvent*))); + connect(m_canvasWidget, TQT_SIGNAL(sigGotMouseWheelEvent(TQWheelEvent*)), TQT_SIGNAL(sigGotMouseWheelEvent(TQWheelEvent*))); + connect(m_canvasWidget, TQT_SIGNAL(sigGotKeyPressEvent(TQKeyEvent*)), TQT_SIGNAL(sigGotKeyPressEvent(TQKeyEvent*))); + connect(m_canvasWidget, TQT_SIGNAL(sigGotKeyReleaseEvent(TQKeyEvent*)), TQT_SIGNAL(sigGotKeyReleaseEvent(TQKeyEvent*))); + connect(m_canvasWidget, TQT_SIGNAL(sigGotDragEnterEvent(TQDragEnterEvent*)), TQT_SIGNAL(sigGotDragEnterEvent(TQDragEnterEvent*))); + connect(m_canvasWidget, TQT_SIGNAL(sigGotDropEvent(TQDropEvent*)), TQT_SIGNAL(sigGotDropEvent(TQDropEvent*))); + connect(m_canvasWidget, TQT_SIGNAL(sigGotMoveEvent(KisMoveEvent *)), TQT_SIGNAL(sigGotMoveEvent(KisMoveEvent *))); + connect(m_canvasWidget, TQT_SIGNAL(sigGotButtonPressEvent(KisButtonPressEvent *)), TQT_SIGNAL(sigGotButtonPressEvent(KisButtonPressEvent *))); + connect(m_canvasWidget, TQT_SIGNAL(sigGotButtonReleaseEvent(KisButtonReleaseEvent *)), TQT_SIGNAL(sigGotButtonReleaseEvent(KisButtonReleaseEvent *))); + connect(m_canvasWidget, TQT_SIGNAL(sigGotDoubleClickEvent(KisDoubleClickEvent *)), TQT_SIGNAL(sigGotDoubleClickEvent(KisDoubleClickEvent *))); +} + +void KisCanvas::createTQPaintDeviceCanvas() +{ + createCanvasWidget(TQPAINTDEVICE_CANVAS_WIDGET); +} + +#ifdef HAVE_GL +void KisCanvas::createOpenGLCanvas(TQGLWidget *sharedContextWidget) +{ + createCanvasWidget(OPENGL_CANVAS_WIDGET, sharedContextWidget); +} +#endif + +bool KisCanvas::isOpenGLCanvas() const +{ + return m_useOpenGL; +} + +void KisCanvas::enableMoveEventCompressionHint(bool enableMoveCompression) +{ + m_enableMoveEventCompressionHint = enableMoveCompression; + if (m_canvasWidget != 0) { + m_canvasWidget->enableMoveEventCompressionHint(enableMoveCompression); + } +} + +TQWidget *KisCanvas::TQPaintDeviceWidget() const +{ + if (m_useOpenGL) { + return 0; + } else { + return dynamic_cast<TQWidget *>(m_canvasWidget); + } +} + +#ifdef HAVE_GL +TQGLWidget *KisCanvas::OpenGLWidget() const +{ + if (m_useOpenGL) { + return dynamic_cast<TQGLWidget *>(m_canvasWidget); + } else { + return 0; + } +} +#endif + +KisCanvasWidgetPainter *KisCanvas::createPainter() +{ + Q_ASSERT(m_canvasWidget != 0); + return m_canvasWidget->createPainter(); +} + +KisCanvasWidget *KisCanvas::canvasWidget() const +{ + return m_canvasWidget; +} + +void KisCanvas::setGeometry(int x, int y, int width, int height) +{ + Q_ASSERT(m_canvasWidget); + dynamic_cast<TQWidget *>(m_canvasWidget)->setGeometry(x, y, width, height); +} + +void KisCanvas::show() +{ + Q_ASSERT(m_canvasWidget); + dynamic_cast<TQWidget *>(m_canvasWidget)->show(); +} + +void KisCanvas::hide() +{ + Q_ASSERT(m_canvasWidget); + dynamic_cast<TQWidget *>(m_canvasWidget)->hide(); +} + +int KisCanvas::width() const +{ + Q_ASSERT(m_canvasWidget); + return dynamic_cast<TQWidget *>(m_canvasWidget)->width(); +} + +int KisCanvas::height() const +{ + Q_ASSERT(m_canvasWidget); + return dynamic_cast<TQWidget *>(m_canvasWidget)->height(); +} + +void KisCanvas::update() +{ + Q_ASSERT(m_canvasWidget); + dynamic_cast<TQWidget *>(m_canvasWidget)->update(); +} + +void KisCanvas::update(const TQRect& r) +{ + Q_ASSERT(m_canvasWidget); + dynamic_cast<TQWidget *>(m_canvasWidget)->update(r); +} + +void KisCanvas::update(int x, int y, int width, int height) +{ + Q_ASSERT(m_canvasWidget); + dynamic_cast<TQWidget *>(m_canvasWidget)->update(x, y, width, height); +} + +void KisCanvas::tqrepaint() +{ + Q_ASSERT(m_canvasWidget); + dynamic_cast<TQWidget *>(m_canvasWidget)->tqrepaint(); +} + +void KisCanvas::tqrepaint(bool erase) +{ + Q_ASSERT(m_canvasWidget); + dynamic_cast<TQWidget *>(m_canvasWidget)->tqrepaint(erase); +} + +void KisCanvas::tqrepaint(int x, int y, int width, int height, bool erase) +{ + Q_ASSERT(m_canvasWidget); + dynamic_cast<TQWidget *>(m_canvasWidget)->tqrepaint(x, y, width, height, erase); +} + +void KisCanvas::tqrepaint(const TQRect& r, bool erase) +{ + Q_ASSERT(m_canvasWidget); + dynamic_cast<TQWidget *>(m_canvasWidget)->tqrepaint(r, erase); +} + +void KisCanvas::tqrepaint(const TQRegion& r, bool erase) +{ + Q_ASSERT(m_canvasWidget); + dynamic_cast<TQWidget *>(m_canvasWidget)->tqrepaint(r, erase); +} + +bool KisCanvas::isUpdatesEnabled() const +{ + Q_ASSERT(m_canvasWidget); + return dynamic_cast<TQWidget *>(m_canvasWidget)->isUpdatesEnabled(); +} + +void KisCanvas::setUpdatesEnabled(bool updatesEnabled) +{ + Q_ASSERT(m_canvasWidget); + dynamic_cast<TQWidget *>(m_canvasWidget)->setUpdatesEnabled(updatesEnabled); +} + +void KisCanvas::updateGeometry() +{ + Q_ASSERT(m_canvasWidget); + dynamic_cast<TQWidget *>(m_canvasWidget)->updateGeometry(); +} + +void KisCanvas::setFocusPolicy(TQ_FocusPolicy focusPolicy) +{ + Q_ASSERT(m_canvasWidget); + dynamic_cast<TQWidget *>(m_canvasWidget)->setFocusPolicy(focusPolicy); +} + +const TQCursor& KisCanvas::cursor() const +{ + Q_ASSERT(m_canvasWidget); + return dynamic_cast<TQWidget *>(m_canvasWidget)->cursor(); +} + +void KisCanvas::setCursor(const TQCursor& cursor) +{ + Q_ASSERT(m_canvasWidget); + dynamic_cast<TQWidget *>(m_canvasWidget)->setCursor(cursor); +} + +#if defined(EXTENDED_X11_TABLET_SUPPORT) +void KisCanvas::selectTabletDeviceEvents() +{ + Q_ASSERT(m_canvasWidget); + m_canvasWidget->selectTabletDeviceEvents(); +} +#endif + +bool KisCanvas::cursorIsOverCanvas() const +{ + if (TQApplication::activePopupWidget() != 0) { + return false; + } + if (TQApplication::activeModalWidget() != 0) { + return false; + } + + TQWidget *canvasWidget = dynamic_cast<TQWidget *>(m_canvasWidget); + Q_ASSERT(canvasWidget != 0); + + if (canvasWidget) { + if (TQApplication::widgetAt(TQCursor::pos(), true) == canvasWidget) { + return true; + } + } + return false; +} + +void KisCanvas::handleKeyEvent(TQEvent *e) +{ + TQKeyEvent *ke = dynamic_cast<TQKeyEvent *>(e); + + Q_ASSERT(ke != 0); + + if (ke) { + TQWidget *canvasWidget = dynamic_cast<TQWidget *>(m_canvasWidget); + Q_ASSERT(canvasWidget != 0); + + if (canvasWidget) { + canvasWidget->setFocus(); + + if (e->type() == TQEvent::KeyPress) { + emit sigGotKeyPressEvent(ke); + } else { + emit sigGotKeyReleaseEvent(ke); + } + } + } +} + +#include "kis_canvas.moc" + diff --git a/chalk/ui/kis_canvas.h b/chalk/ui/kis_canvas.h new file mode 100644 index 00000000..ea36f8a9 --- /dev/null +++ b/chalk/ui/kis_canvas.h @@ -0,0 +1,387 @@ +/* + * Copyright (c) 1999 Matthias Elter <me@kde.org> + * Copyright (c) 2004-2006 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_CANVAS_H_ +#define KIS_CANVAS_H_ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <tqwidget.h> +#ifdef HAVE_GL +#include <tqgl.h> +#endif +#include <tqpainter.h> + +#include "kis_global.h" +#include "kis_point.h" +#include "kis_vec.h" +#include "kis_input_device.h" + +#ifdef Q_MOC_RUN +#define Q_WS_X11 +#endif // Q_MOC_RUN + +#ifdef Q_WS_X11 + +// Irix has a different (and better) XInput tablet driver to +// the XFree/xorg driver. TQt needs a separate code path for that +// and so would we. +#if defined(HAVE_XINPUTEXT) && !defined(Q_OS_IRIX) +#define EXTENDED_X11_TABLET_SUPPORT +#endif + +#include <map> +#include <X11/Xlib.h> + +#if defined(EXTENDED_X11_TABLET_SUPPORT) +#include <X11/extensions/XInput.h> +#endif + +#endif // Q_WS_X11 + +class KisEvent; +class KisMoveEvent; +class KisButtonPressEvent; +class KisButtonReleaseEvent; +class KisDoubleClickEvent; +class KisCanvasWidgetPainter; + +class KisCanvasWidget : public TQObject { + Q_OBJECT + TQ_OBJECT + +public: + KisCanvasWidget(); + virtual ~KisCanvasWidget(); + + // When enabled, the canvas may throw away move events if the application + // is unable to keep up with them, i.e. intermediate move events in the event + // queue are skipped. + void enableMoveEventCompressionHint(bool enableMoveCompression) { m_enableMoveEventCompressionHint = enableMoveCompression; } + + virtual KisCanvasWidgetPainter *createPainter() = 0; + +#ifdef EXTENDED_X11_TABLET_SUPPORT + static KisInputDevice findActiveInputDevice(); + virtual void selectTabletDeviceEvents() = 0; + + static void selectTabletDeviceEvents(TQWidget *widget); +#endif + +#ifdef Q_WS_X11 + static void initX11Support(); +#endif + +signals: + void sigGotPaintEvent(TQPaintEvent*); + void sigGotEnterEvent(TQEvent*); + void sigGotLeaveEvent(TQEvent*); + void sigGotMouseWheelEvent(TQWheelEvent*); + void sigGotKeyPressEvent(TQKeyEvent*); + void sigGotKeyReleaseEvent(TQKeyEvent*); + void sigGotDragEnterEvent(TQDragEnterEvent*); + void sigGotDropEvent(TQDropEvent*); + void sigGotMoveEvent(KisMoveEvent *); + void sigGotButtonPressEvent(KisButtonPressEvent *); + void sigGotButtonReleaseEvent(KisButtonReleaseEvent *); + void sigGotDoubleClickEvent(KisDoubleClickEvent *); + +protected: + void widgetGotPaintEvent(TQPaintEvent *event); + void widgetGotMousePressEvent(TQMouseEvent *event); + void widgetGotMouseReleaseEvent(TQMouseEvent *event); + void widgetGotMouseDoubleClickEvent(TQMouseEvent *event); + void widgetGotMouseMoveEvent(TQMouseEvent *event); + void widgetGotTabletEvent(TQTabletEvent *event); + void widgetGotEnterEvent(TQEvent *event ); + void widgetGotLeaveEvent(TQEvent *event); + void widgetGotWheelEvent(TQWheelEvent *event); + void widgetGotKeyPressEvent(TQKeyEvent *event); + void widgetGotKeyReleaseEvent(TQKeyEvent *event); + void widgetGotDragEnterEvent(TQDragEnterEvent *event); + void widgetGotDropEvent(TQDropEvent *event); + void moveEvent(KisMoveEvent *event); + void buttonPressEvent(KisButtonPressEvent *event); + void buttonReleaseEvent(KisButtonReleaseEvent *event); + void doubleClickEvent(KisDoubleClickEvent *event); + void translateTabletEvent(KisEvent *event); + +protected: + + bool m_enableMoveEventCompressionHint; + double m_lastPressure; + +#ifdef Q_WS_X11 + // On X11 systems, TQt throws away mouse move events if the application + // is unable to keep up with them. We override this behaviour so that + // we receive all move events, so that painting follows the mouse's motion + // accurately. + bool x11Event(XEvent *event, Display *x11Display, WId winId, TQPoint widgetOriginPos); + static TQt::ButtonState translateX11ButtonState(int state); + static TQt::ButtonState translateX11Button(unsigned int button); + + static bool X11SupportInitialised; + + // Modifier tqmasks for alt/meta - detected at run-time + static long X11AltMask; + static long X11MetaMask; + + int m_lastRootX; + int m_lastRootY; + +#ifdef EXTENDED_X11_TABLET_SUPPORT + +public: + class X11TabletDevice + { + public: + X11TabletDevice(); + X11TabletDevice(const XDeviceInfo *deviceInfo); + + bool mightBeTabletDevice() const { return m_mightBeTabletDevice; } + + XID id() const { return m_deviceId; } + XDevice *xDevice() const { return m_XDevice; } + TQString name() const { return m_name; } + + KisInputDevice inputDevice() const { return m_inputDevice; } + void setInputDevice(KisInputDevice inputDevice) { m_inputDevice = inputDevice; } + + void setEnabled(bool enabled); + bool enabled() const; + + TQ_INT32 numAxes() const; + + void setXAxis(TQ_INT32 axis); + void setYAxis(TQ_INT32 axis); + void setPressureAxis(TQ_INT32 axis); + void setXTiltAxis(TQ_INT32 axis); + void setYTiltAxis(TQ_INT32 axis); + void setWheelAxis(TQ_INT32 axis); + void setToolIDAxis(TQ_INT32 axis); + void setSerialNumberAxis(TQ_INT32 axis); + + static const TQ_INT32 NoAxis = -1; + static const TQ_INT32 DefaultAxis = -2; + + TQ_INT32 xAxis() const; + TQ_INT32 yAxis() const; + TQ_INT32 pressureAxis() const; + TQ_INT32 xTiltAxis() const; + TQ_INT32 yTiltAxis() const; + TQ_INT32 wheelAxis() const; + TQ_INT32 toolIDAxis() const; + TQ_INT32 serialNumberAxis() const; + + void readSettingsFromConfig(); + void writeSettingsToConfig(); + + // These return -1 if the device does not support the event + int buttonPressEvent() const { return m_buttonPressEvent; } + int buttonReleaseEvent() const { return m_buttonReleaseEvent; } + int motionNotifyEvent() const { return m_motionNotifyEvent; } + int proximityInEvent() const { return m_proximityInEvent; } + int proximityOutEvent() const { return m_proximityOutEvent; } + + void enableEvents(TQWidget *widget) const; + + class State + { + public: + State() {} + State(const KisPoint& pos, double pressure, const KisVector2D& tilt, double wheel, + TQ_UINT32 toolID, TQ_UINT32 serialNumber); + + // Position, pressure and wheel are normalised to 0 - 1 + KisPoint pos() const { return m_pos; } + double pressure() const { return m_pressure; } + // Tilt is normalised to -1->+1 + KisVector2D tilt() const { return m_tilt; } + double wheel() const { return m_wheel; } + // Wacom tool id and serial number of device. + TQ_UINT32 toolID() const { return m_toolID; } + TQ_UINT32 serialNumber() const { return m_serialNumber; } + + private: + KisPoint m_pos; + double m_pressure; + KisVector2D m_tilt; + double m_wheel; + TQ_UINT32 m_toolID; + TQ_UINT32 m_serialNumber; + }; + + State translateAxisData(const int *axisData) const; + + private: + double translateAxisValue(int value, const XAxisInfo& axisInfo) const; + + XID m_deviceId; + XDevice *m_XDevice; + + TQString m_name; + + bool m_mightBeTabletDevice; + KisInputDevice m_inputDevice; + + bool m_enabled; + + TQ_INT32 m_xAxis; + TQ_INT32 m_yAxis; + TQ_INT32 m_pressureAxis; + TQ_INT32 m_xTiltAxis; + TQ_INT32 m_yTiltAxis; + TQ_INT32 m_wheelAxis; + TQ_INT32 m_toolIDAxis; + TQ_INT32 m_serialNumberAxis; + + TQValueVector<XAxisInfo> m_axisInfo; + + int m_motionNotifyEvent; + int m_buttonPressEvent; + int m_buttonReleaseEvent; + int m_proximityInEvent; + int m_proximityOutEvent; + + TQValueVector<XEventClass> m_eventClassList; + }; + + typedef std::map<XID, X11TabletDevice> X11XIDTabletDeviceMap; + static X11XIDTabletDeviceMap& tabletDeviceMap(); + +protected: + static int X11DeviceMotionNotifyEvent; + static int X11DeviceButtonPressEvent; + static int X11DeviceButtonReleaseEvent; + static int X11ProximityInEvent; + static int X11ProximityOutEvent; + + static X11XIDTabletDeviceMap X11TabletDeviceMap; + +#endif // EXTENDED_X11_TABLET_SUPPORT + +#endif // Q_WS_X11 +}; + +class KisCanvas : public TQObject { + Q_OBJECT + TQ_OBJECT + +public: + KisCanvas(TQWidget *tqparent, const char *name); + virtual ~KisCanvas(); + + // When enabled, the canvas may throw away move events if the application + // is unable to keep up with them, i.e. intermediate move events in the event + // queue are skipped. + void enableMoveEventCompressionHint(bool enableMoveCompression); + + bool isOpenGLCanvas() const; + + /** + * Returns true if the cursor is over the canvas. + */ + bool cursorIsOverCanvas() const; + + /** + * Handle the given event (which must be a key event) as if the canvas + * had received it directly. + */ + void handleKeyEvent(TQEvent *e); + + int width() const; + int height() const; + + void update(); + void update(const TQRect& r); + void update(int x, int y, int width, int height); + void tqrepaint(); + void tqrepaint(bool erase); + void tqrepaint(int x, int y, int width, int height, bool erase = true); + void tqrepaint(const TQRect& r, bool erase = true); + void tqrepaint(const TQRegion& r, bool erase = true); + + void updateGeometry(); + +#if defined(EXTENDED_X11_TABLET_SUPPORT) + void selectTabletDeviceEvents(); +#endif + +signals: + void sigGotPaintEvent(TQPaintEvent*); + void sigGotEnterEvent(TQEvent*); + void sigGotLeaveEvent(TQEvent*); + void sigGotMouseWheelEvent(TQWheelEvent*); + void sigGotKeyPressEvent(TQKeyEvent*); + void sigGotKeyReleaseEvent(TQKeyEvent*); + void sigGotDragEnterEvent(TQDragEnterEvent*); + void sigGotDropEvent(TQDropEvent*); + void sigGotMoveEvent(KisMoveEvent *); + void sigGotButtonPressEvent(KisButtonPressEvent *); + void sigGotButtonReleaseEvent(KisButtonReleaseEvent *); + void sigGotDoubleClickEvent(KisDoubleClickEvent *); + +protected: + // Allow KisView to render on the widget directly, but everything else + // has restricted access. + friend class KisView; + friend class KisCanvasPainter; + + // One of these will be valid, the other null. In TQt3, using a TQPainter on + // a TQGLWidget is not reliable. + TQWidget *TQPaintDeviceWidget() const; +#ifdef HAVE_GL + TQGLWidget *OpenGLWidget() const; +#endif + void createTQPaintDeviceCanvas(); +#ifdef HAVE_GL + void createOpenGLCanvas(TQGLWidget *sharedContextWidget); +#endif + void show(); + void hide(); + void setGeometry(int x, int y, int width, int height); + + void setUpdatesEnabled(bool updatesEnabled); + bool isUpdatesEnabled() const; + + void setFocusPolicy(TQ_FocusPolicy focusPolicy); + + const TQCursor& cursor() const; + void setCursor(const TQCursor& cursor); + + KisCanvasWidgetPainter *createPainter(); + KisCanvasWidget *canvasWidget() const; + +protected: +#ifdef HAVE_GL + void createCanvasWidget(bool useOpenGL, TQGLWidget *sharedContextWidget = 0); +#else + void createCanvasWidget(bool useOpenGL); +#endif + TQWidget *m_parent; + TQString m_name; + KisCanvasWidget *m_canvasWidget; + bool m_enableMoveEventCompressionHint; + bool m_useOpenGL; +}; + +#endif // KIS_CANVAS_H_ + diff --git a/chalk/ui/kis_canvas_painter.cc b/chalk/ui/kis_canvas_painter.cc new file mode 100644 index 00000000..ed5be01d --- /dev/null +++ b/chalk/ui/kis_canvas_painter.cc @@ -0,0 +1,1440 @@ +/* + * Copyright (c) 2005 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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.g + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_qpaintdevice_canvas_painter.h" + +KisCanvasWidgetPainter::KisCanvasWidgetPainter() +{ +} + +KisCanvasWidgetPainter::~KisCanvasWidgetPainter() +{ +} + +bool KisCanvasWidgetPainter::end() +{ + return true; +} + +void KisCanvasWidgetPainter::save() +{ +} + +void KisCanvasWidgetPainter::restore() +{ +} + +TQFontMetrics KisCanvasWidgetPainter::fontMetrics() const +{ + return TQFontMetrics(TQFont()); +} + +TQFontInfo KisCanvasWidgetPainter::fontInfo() const +{ + return TQFontInfo(TQFont()); +} + +const TQFont& KisCanvasWidgetPainter::font() const +{ + return m_defaultFont; +} + +void KisCanvasWidgetPainter::setFont(const TQFont& /*font*/) +{ +} + +const TQPen& KisCanvasWidgetPainter::pen() const +{ + return m_defaultPen; +} + +void KisCanvasWidgetPainter::setPen(const TQPen& /*pen*/) +{ +} + +void KisCanvasWidgetPainter::setPen(Qt::PenStyle /*penStyle*/) +{ +} + +void KisCanvasWidgetPainter::setPen(const TQColor& /*color*/) +{ +} + +const TQBrush& KisCanvasWidgetPainter::brush() const +{ + return m_defaultBrush; +} + +void KisCanvasWidgetPainter::setBrush(const TQBrush& /*brush*/) +{ +} + +void KisCanvasWidgetPainter::setBrush(TQt::BrushStyle /*brushStyle*/) +{ +} + +void KisCanvasWidgetPainter::setBrush(const TQColor& /*color*/) +{ +} + +TQPoint KisCanvasWidgetPainter::pos() const +{ + return TQPoint(); +} + +const TQColor& KisCanvasWidgetPainter::backgroundColor() const +{ + return m_defaultColor; +} + +void KisCanvasWidgetPainter::setBackgroundColor(const TQColor& /*color*/) +{ +} + +Qt::BGMode KisCanvasWidgetPainter::backgroundMode() const +{ + return Qt::TransparentMode; +} + +void KisCanvasWidgetPainter::setBackgroundMode(Qt::BGMode /*bgMode*/) +{ +} + +TQt::RasterOp KisCanvasWidgetPainter::rasterOp() const +{ + return TQt::CopyROP; +} + +void KisCanvasWidgetPainter::setRasterOp(TQt::RasterOp /*rasterOp*/) +{ +} + +const TQPoint& KisCanvasWidgetPainter::brushOrigin() const +{ + return m_defaultBrushOrigin; +} + +void KisCanvasWidgetPainter::setBrushOrigin(int /*x*/, int /*y*/) +{ +} + +void KisCanvasWidgetPainter::setBrushOrigin(const TQPoint& /*origin*/) +{ +} + +bool KisCanvasWidgetPainter::hasViewXForm() const +{ + return false; +} + +bool KisCanvasWidgetPainter::hasWorldXForm() const +{ + return false; +} + +void KisCanvasWidgetPainter::setViewXForm(bool /*enable*/) +{ +} + +TQRect KisCanvasWidgetPainter::window() const +{ + return TQRect(); +} + +void KisCanvasWidgetPainter::setWindow(const TQRect& /*r*/) +{ +} + +void KisCanvasWidgetPainter::setWindow(int /*x*/, int /*y*/, int /*w*/, int /*h*/) +{ +} + +TQRect KisCanvasWidgetPainter::viewport() const +{ + return TQRect(); +} + +void KisCanvasWidgetPainter::setViewport(const TQRect& /*r*/) +{ +} + +void KisCanvasWidgetPainter::setViewport(int /*x*/, int /*y*/, int /*w*/, int /*h*/) +{ +} + + +void KisCanvasWidgetPainter::setWorldXForm(bool /*enable*/) +{ +} + +const TQWMatrix& KisCanvasWidgetPainter::tqworldMatrix() const +{ + return m_defaultWorldMatrix; +} + +void KisCanvasWidgetPainter::setWorldMatrix(const TQWMatrix& /*matrix*/, bool /*combine*/) +{ +} + +void KisCanvasWidgetPainter::saveWorldMatrix() +{ +} + +void KisCanvasWidgetPainter::restoreWorldMatrix() +{ +} + +void KisCanvasWidgetPainter::scale(double /*sx*/, double /*sy*/) +{ +} + +void KisCanvasWidgetPainter::shear(double /*sh*/, double /*sv*/) +{ +} + +void KisCanvasWidgetPainter::rotate(double /*a*/) +{ +} + +void KisCanvasWidgetPainter::translate(double /*dx*/, double /*dy*/) +{ +} + +void KisCanvasWidgetPainter::resetXForm() +{ +} + +double KisCanvasWidgetPainter::translationX() const +{ + return 0; +} + +double KisCanvasWidgetPainter::translationY() const +{ + return 0; +} + +TQPoint KisCanvasWidgetPainter::xForm(const TQPoint& point) const +{ + return point; +} + +TQRect KisCanvasWidgetPainter::xForm(const TQRect& r) const +{ + return r; +} + +TQPointArray KisCanvasWidgetPainter::xForm(const TQPointArray& pointArray) const +{ + return pointArray; +} + +TQPointArray KisCanvasWidgetPainter::xForm(const TQPointArray& pointArray, int /*index*/, int /*npoints*/) const +{ + return pointArray; +} + +TQPoint KisCanvasWidgetPainter::xFormDev(const TQPoint& point) const +{ + return point; +} + +TQRect KisCanvasWidgetPainter::xFormDev(const TQRect& r) const +{ + return r; +} + +TQPointArray KisCanvasWidgetPainter::xFormDev(const TQPointArray& pointArray) const +{ + return pointArray; +} + +TQPointArray KisCanvasWidgetPainter::xFormDev(const TQPointArray& pointArray, int /*index*/, int /*npoints*/) const +{ + return pointArray; +} + +void KisCanvasWidgetPainter::setClipping(bool /*enable*/) +{ +} + +bool KisCanvasWidgetPainter::hasClipping() const +{ + return true; +} + +TQRegion KisCanvasWidgetPainter::clipRegion(TQPainter::CoordinateMode /*mode*/) const +{ + return TQRegion(); +} + +void KisCanvasWidgetPainter::setClipRect(const TQRect& /*r*/, TQPainter::CoordinateMode /*mode*/) +{ +} + +void KisCanvasWidgetPainter::setClipRect(int /*x*/, int /*y*/, int /*w*/, int /*h*/, TQPainter::CoordinateMode /*mode*/) +{ +} + +void KisCanvasWidgetPainter::setClipRegion(const TQRegion& /*rgn*/, TQPainter::CoordinateMode /*mode*/) +{ +} + +void KisCanvasWidgetPainter::drawPoint(int /*x*/, int /*y*/) +{ +} + +void KisCanvasWidgetPainter::drawPoint(const TQPoint& /*point*/) +{ +} + +void KisCanvasWidgetPainter::drawPoints(const TQPointArray& /*pointArray*/, int /*index*/, int /*npoints*/) +{ +} + +void KisCanvasWidgetPainter::moveTo(int /*x*/, int /*y*/) +{ +} + +void KisCanvasWidgetPainter::moveTo(const TQPoint& /*point*/) +{ +} + +void KisCanvasWidgetPainter::lineTo(int /*x*/, int /*y*/) +{ +} + +void KisCanvasWidgetPainter::lineTo(const TQPoint& /*point*/) +{ +} + +void KisCanvasWidgetPainter::drawLine(int /*x1*/, int /*y1*/, int /*x2*/, int /*y2*/) +{ +} + +void KisCanvasWidgetPainter::drawLine(const TQPoint& /*start*/, const TQPoint& /*end*/) +{ +} + +void KisCanvasWidgetPainter::drawRect(int /*x*/, int /*y*/, int /*w*/, int /*h*/) +{ +} + +void KisCanvasWidgetPainter::drawRect(const TQRect& /*r*/) +{ +} + +void KisCanvasWidgetPainter::drawWinFocusRect(int /*x*/, int /*y*/, int /*w*/, int /*h*/) +{ +} + +void KisCanvasWidgetPainter::drawWinFocusRect(int /*x*/, int /*y*/, int /*w*/, int /*h*/, const TQColor& /*bgColor*/) +{ +} + +void KisCanvasWidgetPainter::drawWinFocusRect(const TQRect& /*r*/) +{ +} + +void KisCanvasWidgetPainter::drawWinFocusRect(const TQRect& /*r*/, const TQColor& /*bgColor*/) +{ +} + +void KisCanvasWidgetPainter::drawRoundRect(int /*x*/, int /*y*/, int /*w*/, int /*h*/, int /*xRnd*/, int /*yRnd*/) +{ +} + +void KisCanvasWidgetPainter::drawRoundRect(const TQRect& /*r*/, int /*xRnd*/, int /*yRnd*/) +{ +} + +void KisCanvasWidgetPainter::drawEllipse(int /*x*/, int /*y*/, int /*w*/, int /*h*/) +{ +} + +void KisCanvasWidgetPainter::drawEllipse(const TQRect& /*r*/) +{ +} + +void KisCanvasWidgetPainter::drawArc(int /*x*/, int /*y*/, int /*w*/, int /*h*/, int /*a*/, int /*alen*/) +{ +} + +void KisCanvasWidgetPainter::drawArc(const TQRect& /*r*/, int /*a*/, int /*alen*/) +{ +} + +void KisCanvasWidgetPainter::drawPie(int /*x*/, int /*y*/, int /*w*/, int /*h*/, int /*a*/, int /*alen*/) +{ +} + +void KisCanvasWidgetPainter::drawPie(const TQRect& /*r*/, int /*a*/, int /*alen*/) +{ +} + +void KisCanvasWidgetPainter::drawChord(int /*x*/, int /*y*/, int /*w*/, int /*h*/, int /*a*/, int /*alen*/) +{ +} + +void KisCanvasWidgetPainter::drawChord(const TQRect& /*r*/, int /*a*/, int /*alen*/) +{ +} + +void KisCanvasWidgetPainter::drawLineSegments(const TQPointArray& /*pointArray*/, int /*index*/, int /*nlines*/) +{ +} + +void KisCanvasWidgetPainter::drawPolyline(const TQPointArray& /*pointArray*/, int /*index*/, int /*npoints*/) +{ +} + +void KisCanvasWidgetPainter::drawPolygon(const TQPointArray& /*pointArray*/, bool /*winding*/, int /*index*/, int /*npoints*/) +{ +} + +void KisCanvasWidgetPainter::drawConvexPolygon(const TQPointArray& /*pointArray*/, int /*index*/, int /*npoints*/) +{ +} + +void KisCanvasWidgetPainter::drawCubicBezier(const TQPointArray& /*pointArray*/, int /*index*/) +{ +} + +void KisCanvasWidgetPainter::drawPixmap(int /*x*/, int /*y*/, const TQPixmap& /*pixmap*/, int /*sx*/, int /*sy*/, int /*sw*/, int /*sh*/) +{ +} + +void KisCanvasWidgetPainter::drawPixmap(const TQPoint& /*point*/, const TQPixmap& /*pixmap*/, const TQRect& /*sr*/) +{ +} + +void KisCanvasWidgetPainter::drawPixmap(const TQPoint& /*point*/, const TQPixmap& /*pixmap*/) +{ +} + +void KisCanvasWidgetPainter::drawPixmap(const TQRect& /*r*/, const TQPixmap& /*pixmap*/) +{ +} + +void KisCanvasWidgetPainter::drawImage(int /*x*/, int /*y*/, const TQImage& /*image*/, int /*sx*/, int /*sy*/, int /*sw*/, int /*sh*/, int /*conversionFlags*/) +{ +} + +void KisCanvasWidgetPainter::drawImage(const TQPoint& /*point*/, const TQImage& /*image*/, const TQRect& /*sr*/, int /*conversionFlags*/) +{ +} + +void KisCanvasWidgetPainter::drawImage(const TQPoint& /*point*/, const TQImage& /*image*/, int /*conversion_flags*/) +{ +} + +void KisCanvasWidgetPainter::drawImage(const TQRect& /*r*/, const TQImage& /*image*/) +{ +} + +void KisCanvasWidgetPainter::drawTiledPixmap(int /*x*/, int /*y*/, int /*w*/, int /*h*/, const TQPixmap& /*pixmap*/, int /*sx*/, int /*sy*/) +{ +} + +void KisCanvasWidgetPainter::drawTiledPixmap(const TQRect& /*r*/, const TQPixmap& /*pixmap*/, const TQPoint& /*point*/) +{ +} + +void KisCanvasWidgetPainter::drawTiledPixmap(const TQRect& /*r*/, const TQPixmap& /*pixmap*/) +{ +} + +void KisCanvasWidgetPainter::fillRect(int /*x*/, int /*y*/, int /*w*/, int /*h*/, const TQBrush& /*brush*/) +{ +} + +void KisCanvasWidgetPainter::fillRect(const TQRect& /*r*/, const TQBrush& /*brush*/) +{ +} + +void KisCanvasWidgetPainter::eraseRect(int /*x*/, int /*y*/, int /*w*/, int /*h*/) +{ +} + +void KisCanvasWidgetPainter::eraseRect(const TQRect& /*r*/) +{ +} + +void KisCanvasWidgetPainter::drawText(int /*x*/, int /*y*/, const TQString& /*text*/, int /*len*/, TQPainter::TextDirection /*dir*/) +{ +} + +void KisCanvasWidgetPainter::drawText(const TQPoint& /*point*/, const TQString& /*text*/, int /*len*/, TQPainter::TextDirection /*dir*/) +{ +} + +void KisCanvasWidgetPainter::drawText(int /*x*/, int /*y*/, const TQString& /*text*/, int /*pos*/, int /*len*/, TQPainter::TextDirection /*dir*/) +{ +} + +void KisCanvasWidgetPainter::drawText(const TQPoint& /*point*/, const TQString& /*text*/, int /*pos*/, int /*len*/, TQPainter::TextDirection /*dir*/) +{ +} + +void KisCanvasWidgetPainter::drawText(int /*x*/, int /*y*/, int /*w*/, int /*h*/, int /*flags*/, const TQString& /*text*/, int /*len*/, TQRect */*br*/, TQTextParag **/*intern*/) +{ +} + +void KisCanvasWidgetPainter::drawText(const TQRect& /*r*/, int /*flags*/, const TQString& /*text*/, int /*len*/, TQRect */*br*/, TQTextParag **/*intern*/) +{ +} + +void KisCanvasWidgetPainter::tqdrawTextItem(int /*x*/, int /*y*/, const TQTextItem& /*ti*/, int /*textflags*/) +{ +} + +void KisCanvasWidgetPainter::tqdrawTextItem(const TQPoint& /*p*/, const TQTextItem& /*ti*/, int /*textflags*/) +{ +} + +TQRect KisCanvasWidgetPainter::boundingRect(int /*x*/, int /*y*/, int /*w*/, int /*h*/, int /*flags*/, const TQString& /*text*/, int /*len*/, TQTextParag **/*intern*/) +{ + return TQRect(); +} + +TQRect KisCanvasWidgetPainter::boundingRect(const TQRect& /*r*/, int /*flags*/, const TQString& /*text*/, int /*len*/, TQTextParag **/*intern*/) +{ + return TQRect(); +} + +int KisCanvasWidgetPainter::tabStops() const +{ + return 0; +} + +void KisCanvasWidgetPainter::setTabStops(int /*ts*/) +{ +} + +int *KisCanvasWidgetPainter::tabArray() const +{ + return 0; +} + +void KisCanvasWidgetPainter::setTabArray(int */*ts*/) +{ +} + +/*************************************************************************/ + +KisCanvasPainter::KisCanvasPainter() +{ + m_canvasWidgetPainter = 0; +} + +KisCanvasPainter::KisCanvasPainter(KisCanvas *canvas) +{ + m_canvasWidgetPainter = canvas->createPainter(); +} + +KisCanvasPainter::KisCanvasPainter(const TQPaintDevice *paintDevice) +{ + m_canvasWidgetPainter = new KisTQPaintDeviceCanvasPainter(paintDevice); +} + +KisCanvasPainter::~KisCanvasPainter() +{ + delete m_canvasWidgetPainter; +} + +bool KisCanvasPainter::begin(KisCanvas *canvas, bool unclipped) +{ + delete m_canvasWidgetPainter; + m_canvasWidgetPainter = canvas->createPainter(); + return m_canvasWidgetPainter->begin(canvas->canvasWidget(), unclipped); +} + +bool KisCanvasPainter::begin(const TQPaintDevice *paintDevice, bool unclipped) +{ + delete m_canvasWidgetPainter; + m_canvasWidgetPainter = new KisTQPaintDeviceCanvasPainter(); + return static_cast<KisTQPaintDeviceCanvasPainter *>(m_canvasWidgetPainter)->begin(paintDevice, unclipped); +} + +bool KisCanvasPainter::end() +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->end(); + } + return false; +} + +void KisCanvasPainter::save() +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->save(); + } +} + +void KisCanvasPainter::restore() +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->restore(); + } +} + +TQFontMetrics KisCanvasPainter::fontMetrics() const +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->fontMetrics(); + } + return TQFontMetrics(TQFont()); +} + +TQFontInfo KisCanvasPainter::fontInfo() const +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->fontInfo(); + } + return TQFontInfo(TQFont()); +} + +const TQFont& KisCanvasPainter::font() const +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->font(); + } + return m_defaultFont; +} + +void KisCanvasPainter::setFont(const TQFont& font) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->setFont(font); + } +} + +const TQPen& KisCanvasPainter::pen() const +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->pen(); + } + return m_defaultPen; +} + +void KisCanvasPainter::setPen(const TQPen& pen) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->setPen(pen); + } +} + +void KisCanvasPainter::setPen(Qt::PenStyle penStyle) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->setPen(penStyle); + } +} + +void KisCanvasPainter::setPen(const TQColor& color) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->setPen(color);; + } +} + +const TQBrush& KisCanvasPainter::brush() const +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->brush(); + } + return m_defaultBrush; +} + +void KisCanvasPainter::setBrush(const TQBrush& brush) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->setBrush(brush); + } +} + +void KisCanvasPainter::setBrush(TQt::BrushStyle brushStyle) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->setBrush(brushStyle); + } +} + +void KisCanvasPainter::setBrush(const TQColor& color) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->setBrush(color); + } +} + +TQPoint KisCanvasPainter::pos() const +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->pos(); + } + return TQPoint(); +} + +const TQColor& KisCanvasPainter::backgroundColor() const +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->backgroundColor(); + } + return m_defaultColor; +} + +void KisCanvasPainter::setBackgroundColor(const TQColor& color) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->setBackgroundColor(color); + } +} + +Qt::BGMode KisCanvasPainter::backgroundMode() const +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->backgroundMode(); + } + return Qt::TransparentMode; +} + +void KisCanvasPainter::setBackgroundMode(Qt::BGMode bgMode) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->setBackgroundMode(bgMode); + } +} + +TQt::RasterOp KisCanvasPainter::rasterOp() const +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->rasterOp(); + } + return TQt::CopyROP; +} + +void KisCanvasPainter::setRasterOp(TQt::RasterOp rasterOp) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->setRasterOp(rasterOp); + } +} + +const TQPoint& KisCanvasPainter::brushOrigin() const +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->brushOrigin(); + } + return m_defaultBrushOrigin; +} + +void KisCanvasPainter::setBrushOrigin(int x, int y) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->setBrushOrigin(x, y); + } +} + +void KisCanvasPainter::setBrushOrigin(const TQPoint& origin) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->setBrushOrigin(origin); + } +} + +bool KisCanvasPainter::hasViewXForm() const +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->hasViewXForm(); + } + return false; +} + +bool KisCanvasPainter::hasWorldXForm() const +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->hasWorldXForm(); + } + return false; +} + +void KisCanvasPainter::setViewXForm(bool enable) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->setViewXForm(enable); + } +} + +TQRect KisCanvasPainter::window() const +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->window(); + } + return TQRect(); +} + +void KisCanvasPainter::setWindow(const TQRect& r) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->setWindow(r); + } +} + +void KisCanvasPainter::setWindow(int x, int y, int w, int h) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->setWindow(x, y, w, h); + } +} + +TQRect KisCanvasPainter::viewport() const +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->viewport(); + } + return TQRect(); +} + +void KisCanvasPainter::setViewport(const TQRect& r) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->setViewport(r); + } +} + +void KisCanvasPainter::setViewport(int x, int y, int w, int h) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->setViewport(x, y, w, h); + } +} + +void KisCanvasPainter::setWorldXForm(bool enable) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->setWorldXForm(enable); + } +} + +const TQWMatrix& KisCanvasPainter::tqworldMatrix() const +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->tqworldMatrix(); + } + return m_defaultWorldMatrix; +} + +void KisCanvasPainter::setWorldMatrix(const TQWMatrix& matrix, bool combine) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->setWorldMatrix(matrix, combine); + } +} + +void KisCanvasPainter::saveWorldMatrix() +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->saveWorldMatrix(); + } +} + +void KisCanvasPainter::restoreWorldMatrix() +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->restoreWorldMatrix(); + } +} + +void KisCanvasPainter::scale(double sx, double sy) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->scale(sx, sy); + } +} + +void KisCanvasPainter::shear(double sh, double sv) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->shear(sh, sv); + } +} + +void KisCanvasPainter::rotate(double a) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->rotate(a); + } +} + +void KisCanvasPainter::translate(double dx, double dy) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->translate(dx, dy); + } +} + +void KisCanvasPainter::resetXForm() +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->resetXForm(); + } +} + +double KisCanvasPainter::translationX() const +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->translationX(); + } + return 0; +} + +double KisCanvasPainter::translationY() const +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->translationY(); + } + return 0; +} + +TQPoint KisCanvasPainter::xForm(const TQPoint& point) const +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->xForm(point); + } + return point; +} + +TQRect KisCanvasPainter::xForm(const TQRect& r) const +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->xForm(r); + } + return r; +} + +TQPointArray KisCanvasPainter::xForm(const TQPointArray& pointArray) const +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->xForm(pointArray); + } + return pointArray; +} + +TQPointArray KisCanvasPainter::xForm(const TQPointArray& pointArray, int index, int npoints) const +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->xForm(pointArray, index, npoints); + } + return pointArray; +} + +TQPoint KisCanvasPainter::xFormDev(const TQPoint& point) const +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->xFormDev(point); + } + return point; +} + +TQRect KisCanvasPainter::xFormDev(const TQRect& r) const +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->xFormDev(r); + } + return r; +} + +TQPointArray KisCanvasPainter::xFormDev(const TQPointArray& pointArray) const +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->xFormDev(pointArray); + } + return pointArray; +} + +TQPointArray KisCanvasPainter::xFormDev(const TQPointArray& pointArray, int index, int npoints) const +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->xFormDev(pointArray, index, npoints); + } + return pointArray; +} + +void KisCanvasPainter::setClipping(bool enable) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->setClipping(enable); + } +} + +bool KisCanvasPainter::hasClipping() const +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->hasClipping(); + } + return true; +} + +TQRegion KisCanvasPainter::clipRegion(TQPainter::CoordinateMode mode) const +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->clipRegion(mode); + } + return TQRegion(); +} + +void KisCanvasPainter::setClipRect(const TQRect& r, TQPainter::CoordinateMode mode) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->setClipRect(r, mode); + } +} + +void KisCanvasPainter::setClipRect(int x, int y, int w, int h, TQPainter::CoordinateMode mode) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->setClipRect(x, y, w, h, mode); + } +} + +void KisCanvasPainter::setClipRegion(const TQRegion& rgn, TQPainter::CoordinateMode mode) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->setClipRegion(rgn, mode); + } +} + +void KisCanvasPainter::drawPoint(int x, int y) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawPoint(x, y); + } +} + +void KisCanvasPainter::drawPoint(const TQPoint& point) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawPoint(point); + } +} + +void KisCanvasPainter::drawPoints(const TQPointArray& pointArray, int index, int npoints) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawPoints(pointArray, index, npoints); + } +} + +void KisCanvasPainter::moveTo(int x, int y) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->moveTo(x, y); + } +} + +void KisCanvasPainter::moveTo(const TQPoint& point) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->moveTo(point); + } +} + +void KisCanvasPainter::lineTo(int x, int y) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->lineTo(x, y); + } +} + +void KisCanvasPainter::lineTo(const TQPoint& point) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->lineTo(point); + } +} + +void KisCanvasPainter::drawLine(int x1, int y1, int x2, int y2) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawLine(x1, y1, x2, y2); + } +} + +void KisCanvasPainter::drawLine(const TQPoint& start, const TQPoint& end) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawLine(start, end); + } +} + +void KisCanvasPainter::drawRect(int x, int y, int w, int h) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawRect(x, y, w, h); + } +} + +void KisCanvasPainter::drawRect(const TQRect& r) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawRect(r); + } +} + +void KisCanvasPainter::drawWinFocusRect(int x, int y, int w, int h) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawWinFocusRect(x, y, w, h); + } +} + +void KisCanvasPainter::drawWinFocusRect(int x, int y, int w, int h, const TQColor& bgColor) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawWinFocusRect(x, y, w, h, bgColor); + } +} + +void KisCanvasPainter::drawWinFocusRect(const TQRect& r) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawWinFocusRect(r); + } +} + +void KisCanvasPainter::drawWinFocusRect(const TQRect& r, const TQColor& bgColor) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawWinFocusRect(r, bgColor); + } +} + +void KisCanvasPainter::drawRoundRect(int x, int y, int w, int h, int xRnd, int yRnd) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawRoundRect(x, y, w, h, xRnd, yRnd); + } +} + +void KisCanvasPainter::drawRoundRect(const TQRect& r, int xRnd, int yRnd) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawRoundRect(r, xRnd, yRnd); + } +} + +void KisCanvasPainter::drawEllipse(int x, int y, int w, int h) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawEllipse(x, y, w, h); + } +} + +void KisCanvasPainter::drawEllipse(const TQRect& r) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawEllipse(r); + } +} + +void KisCanvasPainter::drawArc(int x, int y, int w, int h, int a, int alen) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawArc(x, y, w, h, a, alen); + } +} + +void KisCanvasPainter::drawArc(const TQRect& r, int a, int alen) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawArc(r, a, alen); + } +} + +void KisCanvasPainter::drawPie(int x, int y, int w, int h, int a, int alen) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawPie(x, y, w, h, a, alen); + } +} + +void KisCanvasPainter::drawPie(const TQRect& r, int a, int alen) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawPie(r, a, alen); + } +} + +void KisCanvasPainter::drawChord(int x, int y, int w, int h, int a, int alen) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawChord(x, y, w, h, a, alen); + } +} + +void KisCanvasPainter::drawChord(const TQRect& r, int a, int alen) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawChord(r, a, alen); + } +} + +void KisCanvasPainter::drawLineSegments(const TQPointArray& pointArray, int index, int nlines) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawLineSegments(pointArray, index, nlines); + } +} + +void KisCanvasPainter::drawPolyline(const TQPointArray& pointArray, int index, int npoints) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawPolyline(pointArray, index, npoints); + } +} + +void KisCanvasPainter::drawPolygon(const TQPointArray& pointArray, bool winding, int index, int npoints) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawPolygon(pointArray, winding, index, npoints); + } +} + +void KisCanvasPainter::drawConvexPolygon(const TQPointArray& pointArray, int index, int npoints) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawConvexPolygon(pointArray, index, npoints); + } +} + +void KisCanvasPainter::drawCubicBezier(const TQPointArray& pointArray, int index) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawCubicBezier(pointArray, index); + } +} + +void KisCanvasPainter::drawPixmap(int x, int y, const TQPixmap& pixmap, int sx, int sy, int sw, int sh) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawPixmap(x, y, pixmap, sx, sy, sw, sh); + } +} + +void KisCanvasPainter::drawPixmap(const TQPoint& point, const TQPixmap& pixmap, const TQRect& sr) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawPixmap(point, pixmap, sr); + } +} + +void KisCanvasPainter::drawPixmap(const TQPoint& point, const TQPixmap& pixmap) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawPixmap(point, pixmap); + } +} + +void KisCanvasPainter::drawPixmap(const TQRect& r, const TQPixmap& pixmap) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawPixmap(r, pixmap); + } +} + +void KisCanvasPainter::drawImage(int x, int y, const TQImage& image, int sx, int sy, int sw, int sh, int conversionFlags) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawImage(x, y, image, sx, sy, sw, sh, conversionFlags); + } +} + +void KisCanvasPainter::drawImage(const TQPoint& point, const TQImage& image, const TQRect& sr, int conversionFlags) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawImage(point, image, sr, conversionFlags); + } +} + +void KisCanvasPainter::drawImage(const TQPoint& point, const TQImage& image, int conversion_flags) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawImage(point, image, conversion_flags); + } +} + +void KisCanvasPainter::drawImage(const TQRect& r, const TQImage& image) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawImage(r, image); + } +} + +void KisCanvasPainter::drawTiledPixmap(int x, int y, int w, int h, const TQPixmap& pixmap, int sx, int sy) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawTiledPixmap(x, y, w, h, pixmap, sx, sy); + } +} + +void KisCanvasPainter::drawTiledPixmap(const TQRect& r, const TQPixmap& pixmap, const TQPoint& point) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawTiledPixmap(r, pixmap, point); + } +} + +void KisCanvasPainter::drawTiledPixmap(const TQRect& r, const TQPixmap& pixmap) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawTiledPixmap(r, pixmap); + } +} + +void KisCanvasPainter::fillRect(int x, int y, int w, int h, const TQBrush& brush) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->fillRect(x, y, w, h, brush); + } +} + +void KisCanvasPainter::fillRect(const TQRect& r, const TQBrush& brush) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->fillRect(r, brush); + } +} + +void KisCanvasPainter::eraseRect(int x, int y, int w, int h) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->eraseRect(x, y, w, h); + } +} + +void KisCanvasPainter::eraseRect(const TQRect& r) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->eraseRect(r); + } +} + +void KisCanvasPainter::drawText(int x, int y, const TQString& text, int len, TQPainter::TextDirection dir) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawText(x, y, text, len, dir); + } +} + +void KisCanvasPainter::drawText(const TQPoint& point, const TQString& text, int len, TQPainter::TextDirection dir) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawText(point, text, len, dir); + } +} + +void KisCanvasPainter::drawText(int x, int y, const TQString& text, int pos, int len, TQPainter::TextDirection dir) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawText(x, y, text, pos, len, dir); + } +} + +void KisCanvasPainter::drawText(const TQPoint& point, const TQString& text, int pos, int len, TQPainter::TextDirection dir) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawText(point, text, pos, len, dir); + } +} + +void KisCanvasPainter::drawText(int x, int y, int w, int h, int flags, const TQString& text, int len, TQRect *br, TQTextParag **intern) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawText(x, y, w, h, flags, text, len, br, intern); + } +} + +void KisCanvasPainter::drawText(const TQRect& r, int flags, const TQString& text, int len, TQRect *br, TQTextParag **intern) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->drawText(r, flags, text, len, br, intern); + } +} + +void KisCanvasPainter::tqdrawTextItem(int x, int y, const TQTextItem& ti, int textflags) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->tqdrawTextItem(x, y, ti, textflags); + } +} + +void KisCanvasPainter::tqdrawTextItem(const TQPoint& p, const TQTextItem& ti, int textflags) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->tqdrawTextItem(p, ti, textflags); + } +} + +TQRect KisCanvasPainter::boundingRect(int x, int y, int w, int h, int flags, const TQString& text, int len, TQTextParag **intern) +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->boundingRect(x, y, w, h, flags, text, len, intern); + } + return TQRect(); +} + +TQRect KisCanvasPainter::boundingRect(const TQRect& r, int flags, const TQString& text, int len, TQTextParag **intern) +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->boundingRect(r, flags, text, len, intern); + } + return TQRect(); +} + +int KisCanvasPainter::tabStops() const +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->tabStops(); + } + return 0; +} + +void KisCanvasPainter::setTabStops(int ts) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->setTabStops(ts); + } +} + +int *KisCanvasPainter::tabArray() const +{ + if (m_canvasWidgetPainter != 0) { + return m_canvasWidgetPainter->tabArray(); + } + return 0; +} + +void KisCanvasPainter::setTabArray(int *ts) +{ + if (m_canvasWidgetPainter != 0) { + m_canvasWidgetPainter->setTabArray(ts); + } +} + diff --git a/chalk/ui/kis_canvas_painter.h b/chalk/ui/kis_canvas_painter.h new file mode 100644 index 00000000..9a719eea --- /dev/null +++ b/chalk/ui/kis_canvas_painter.h @@ -0,0 +1,356 @@ +/* + * Copyright (c) 2005 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_CANVAS_PAINTER_H_ +#define KIS_CANVAS_PAINTER_H_ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <tqpainter.h> + +#include "kis_global.h" + +class KisCanvas; +class KisCanvasWidget; + +class KisCanvasWidgetPainter { +public: + KisCanvasWidgetPainter(); + virtual ~KisCanvasWidgetPainter(); + + virtual bool begin(KisCanvasWidget *canvasWidget, bool unclipped = false) = 0; + virtual bool end(); + + virtual void save(); + virtual void restore(); + + virtual TQFontMetrics fontMetrics() const; + virtual TQFontInfo fontInfo() const; + + virtual const TQFont& font() const; + virtual void setFont(const TQFont&); + virtual const TQPen& pen() const; + virtual void setPen(const TQPen&); + virtual void setPen(Qt::PenStyle); + virtual void setPen(const TQColor&); + virtual const TQBrush&brush() const; + virtual void setBrush(const TQBrush&); + virtual void setBrush(TQt::BrushStyle); + virtual void setBrush(const TQColor&); + virtual TQPoint pos() const; + + virtual const TQColor&backgroundColor() const; + virtual void setBackgroundColor(const TQColor&); + virtual Qt::BGMode backgroundMode() const; + virtual void setBackgroundMode(Qt::BGMode); + virtual TQt::RasterOp rasterOp() const; + virtual void setRasterOp(TQt::RasterOp); + virtual const TQPoint&brushOrigin() const; + virtual void setBrushOrigin(int x, int y); + virtual void setBrushOrigin(const TQPoint&); + + virtual bool hasViewXForm() const; + virtual bool hasWorldXForm() const; + + virtual void setViewXForm(bool); + virtual TQRect window() const; + virtual void setWindow(const TQRect&); + virtual void setWindow(int x, int y, int w, int h); + virtual TQRect viewport() const; + virtual void setViewport(const TQRect&); + virtual void setViewport(int x, int y, int w, int h); + + virtual void setWorldXForm(bool); + virtual const TQWMatrix&tqworldMatrix() const; + virtual void setWorldMatrix(const TQWMatrix&, bool combine=FALSE); + + virtual void saveWorldMatrix(); + virtual void restoreWorldMatrix(); + + virtual void scale(double sx, double sy); + virtual void shear(double sh, double sv); + virtual void rotate(double a); + + virtual void translate(double dx, double dy); + virtual void resetXForm(); + virtual double translationX() const; + virtual double translationY() const; + + virtual TQPoint xForm(const TQPoint&) const; + virtual TQRect xForm(const TQRect&) const; + virtual TQPointArray xForm(const TQPointArray&) const; + virtual TQPointArray xForm(const TQPointArray&, int index, int npoints) const; + virtual TQPoint xFormDev(const TQPoint&) const; + virtual TQRect xFormDev(const TQRect&) const; + virtual TQPointArray xFormDev(const TQPointArray&) const; + virtual TQPointArray xFormDev(const TQPointArray&, int index, int npoints) const; + + virtual void setClipping(bool); + virtual bool hasClipping() const; + virtual TQRegion clipRegion(TQPainter::CoordinateMode = TQPainter::CoordDevice) const; + virtual void setClipRect(const TQRect&, TQPainter::CoordinateMode = TQPainter::CoordDevice); + virtual void setClipRect(int x, int y, int w, int h, TQPainter::CoordinateMode = TQPainter::CoordDevice); + virtual void setClipRegion(const TQRegion&, TQPainter::CoordinateMode = TQPainter::CoordDevice); + + virtual void drawPoint(int x, int y); + virtual void drawPoint(const TQPoint&); + virtual void drawPoints(const TQPointArray& a, int index=0, int npoints=-1); + virtual void moveTo(int x, int y); + virtual void moveTo(const TQPoint&); + virtual void lineTo(int x, int y); + virtual void lineTo(const TQPoint&); + virtual void drawLine(int x1, int y1, int x2, int y2); + virtual void drawLine(const TQPoint&, const TQPoint&); + virtual void drawRect(int x, int y, int w, int h); + virtual void drawRect(const TQRect&); + virtual void drawWinFocusRect(int x, int y, int w, int h); + virtual void drawWinFocusRect(int x, int y, int w, int h, const TQColor&bgColor); + virtual void drawWinFocusRect(const TQRect&); + virtual void drawWinFocusRect(const TQRect&, const TQColor&bgColor); + virtual void drawRoundRect(int x, int y, int w, int h, int = 25, int = 25); + virtual void drawRoundRect(const TQRect&, int = 25, int = 25); + virtual void drawEllipse(int x, int y, int w, int h); + virtual void drawEllipse(const TQRect&); + virtual void drawArc(int x, int y, int w, int h, int a, int alen); + virtual void drawArc(const TQRect&, int a, int alen); + virtual void drawPie(int x, int y, int w, int h, int a, int alen); + virtual void drawPie(const TQRect&, int a, int alen); + virtual void drawChord(int x, int y, int w, int h, int a, int alen); + virtual void drawChord(const TQRect&, int a, int alen); + virtual void drawLineSegments(const TQPointArray&, int index=0, int nlines=-1); + virtual void drawPolyline(const TQPointArray&, int index=0, int npoints=-1); + virtual void drawPolygon(const TQPointArray&, bool winding=FALSE, int index=0, int npoints=-1); + virtual void drawConvexPolygon(const TQPointArray&, int index=0, int npoints=-1); + virtual void drawCubicBezier(const TQPointArray&, int index=0); + virtual void drawPixmap(int x, int y, const TQPixmap&, int sx=0, int sy=0, int sw=-1, int sh=-1); + virtual void drawPixmap(const TQPoint&, const TQPixmap&, const TQRect&sr); + virtual void drawPixmap(const TQPoint&, const TQPixmap&); + virtual void drawPixmap(const TQRect&, const TQPixmap&); + virtual void drawImage(int x, int y, const TQImage&, int sx = 0, int sy = 0, int sw = -1, int sh = -1, int conversionFlags = 0); + virtual void drawImage(const TQPoint&, const TQImage&, const TQRect&sr, int conversionFlags = 0); + virtual void drawImage(const TQPoint&, const TQImage&, int conversion_flags = 0); + virtual void drawImage(const TQRect&, const TQImage&); + virtual void drawTiledPixmap(int x, int y, int w, int h, const TQPixmap&, int sx=0, int sy=0); + virtual void drawTiledPixmap(const TQRect&, const TQPixmap&, const TQPoint&); + virtual void drawTiledPixmap(const TQRect&, const TQPixmap&); + //virtual void drawPicture(const TQPicture&); + //virtual void drawPicture(int x, int y, const TQPicture&); + //virtual void drawPicture(const TQPoint&, const TQPicture&); + + virtual void fillRect(int x, int y, int w, int h, const TQBrush&); + virtual void fillRect(const TQRect&, const TQBrush&); + virtual void eraseRect(int x, int y, int w, int h); + virtual void eraseRect(const TQRect&); + + virtual void drawText(int x, int y, const TQString&, int len = -1, TQPainter::TextDirection dir = TQPainter::Auto); + virtual void drawText(const TQPoint&, const TQString&, int len = -1, TQPainter::TextDirection dir = TQPainter::Auto); + + virtual void drawText(int x, int y, const TQString&, int pos, int len, TQPainter::TextDirection dir = TQPainter::Auto); + virtual void drawText(const TQPoint&p, const TQString&, int pos, int len, TQPainter::TextDirection dir = TQPainter::Auto); + + virtual void drawText(int x, int y, int w, int h, int flags, const TQString&, int len = -1, TQRect *br=0, TQTextParag **intern=0); + virtual void drawText(const TQRect&, int flags, const TQString&, int len = -1, TQRect *br=0, TQTextParag **intern=0); + + virtual void tqdrawTextItem(int x, int y, const TQTextItem&ti, int textflags = 0); + virtual void tqdrawTextItem(const TQPoint& p, const TQTextItem&ti, int textflags = 0); + + virtual TQRect boundingRect(int x, int y, int w, int h, int flags, const TQString&, int len = -1, TQTextParag **intern=0); + virtual TQRect boundingRect(const TQRect&, int flags, const TQString&, int len = -1, TQTextParag **intern=0); + + virtual int tabStops() const; + virtual void setTabStops(int); + virtual int *tabArray() const; + virtual void setTabArray(int *); + +protected: + TQFont m_defaultFont; + TQPen m_defaultPen; + TQBrush m_defaultBrush; + TQColor m_defaultColor; + TQPoint m_defaultBrushOrigin; + TQWMatrix m_defaultWorldMatrix; +}; + +class KisCanvasPainter { +public: + KisCanvasPainter(); + KisCanvasPainter(KisCanvas *canvas); + KisCanvasPainter(const TQPaintDevice *paintDevice); + + ~KisCanvasPainter(); + + bool begin(KisCanvas *canvas, bool unclipped = false); + bool begin(const TQPaintDevice *paintDevice, bool unclipped = false); + + bool end(); + + void save(); + void restore(); + + TQFontMetrics fontMetrics() const; + TQFontInfo fontInfo() const; + + const TQFont& font() const; + void setFont(const TQFont&); + const TQPen& pen() const; + void setPen(const TQPen&); + void setPen(Qt::PenStyle); + void setPen(const TQColor&); + const TQBrush&brush() const; + void setBrush(const TQBrush&); + void setBrush(TQt::BrushStyle); + void setBrush(const TQColor&); + TQPoint pos() const; + + const TQColor&backgroundColor() const; + void setBackgroundColor(const TQColor&); + Qt::BGMode backgroundMode() const; + void setBackgroundMode(Qt::BGMode); + TQt::RasterOp rasterOp() const; + void setRasterOp(TQt::RasterOp); + const TQPoint&brushOrigin() const; + void setBrushOrigin(int x, int y); + void setBrushOrigin(const TQPoint&); + + bool hasViewXForm() const; + bool hasWorldXForm() const; + + void setViewXForm(bool); + TQRect window() const; + void setWindow(const TQRect&); + void setWindow(int x, int y, int w, int h); + TQRect viewport() const; + void setViewport(const TQRect&); + void setViewport(int x, int y, int w, int h); + + void setWorldXForm(bool); + const TQWMatrix&tqworldMatrix() const; + void setWorldMatrix(const TQWMatrix&, bool combine=FALSE); + + void saveWorldMatrix(); + void restoreWorldMatrix(); + + void scale(double sx, double sy); + void shear(double sh, double sv); + void rotate(double a); + + void translate(double dx, double dy); + void resetXForm(); + double translationX() const; + double translationY() const; + + TQPoint xForm(const TQPoint&) const; + TQRect xForm(const TQRect&) const; + TQPointArray xForm(const TQPointArray&) const; + TQPointArray xForm(const TQPointArray&, int index, int npoints) const; + TQPoint xFormDev(const TQPoint&) const; + TQRect xFormDev(const TQRect&) const; + TQPointArray xFormDev(const TQPointArray&) const; + TQPointArray xFormDev(const TQPointArray&, int index, int npoints) const; + + void setClipping(bool); + bool hasClipping() const; + TQRegion clipRegion(TQPainter::CoordinateMode = TQPainter::CoordDevice) const; + void setClipRect(const TQRect&, TQPainter::CoordinateMode = TQPainter::CoordDevice); + void setClipRect(int x, int y, int w, int h, TQPainter::CoordinateMode = TQPainter::CoordDevice); + void setClipRegion(const TQRegion&, TQPainter::CoordinateMode = TQPainter::CoordDevice); + + void drawPoint(int x, int y); + void drawPoint(const TQPoint&); + void drawPoints(const TQPointArray& a, int index=0, int npoints=-1); + void moveTo(int x, int y); + void moveTo(const TQPoint&); + void lineTo(int x, int y); + void lineTo(const TQPoint&); + void drawLine(int x1, int y1, int x2, int y2); + void drawLine(const TQPoint&, const TQPoint&); + void drawRect(int x, int y, int w, int h); + void drawRect(const TQRect&); + void drawWinFocusRect(int x, int y, int w, int h); + void drawWinFocusRect(int x, int y, int w, int h, const TQColor&bgColor); + void drawWinFocusRect(const TQRect&); + void drawWinFocusRect(const TQRect&, const TQColor&bgColor); + void drawRoundRect(int x, int y, int w, int h, int = 25, int = 25); + void drawRoundRect(const TQRect&, int = 25, int = 25); + void drawEllipse(int x, int y, int w, int h); + void drawEllipse(const TQRect&); + void drawArc(int x, int y, int w, int h, int a, int alen); + void drawArc(const TQRect&, int a, int alen); + void drawPie(int x, int y, int w, int h, int a, int alen); + void drawPie(const TQRect&, int a, int alen); + void drawChord(int x, int y, int w, int h, int a, int alen); + void drawChord(const TQRect&, int a, int alen); + void drawLineSegments(const TQPointArray&, int index=0, int nlines=-1); + void drawPolyline(const TQPointArray&, int index=0, int npoints=-1); + void drawPolygon(const TQPointArray&, bool winding=FALSE, int index=0, int npoints=-1); + void drawConvexPolygon(const TQPointArray&, int index=0, int npoints=-1); + void drawCubicBezier(const TQPointArray&, int index=0); + void drawPixmap(int x, int y, const TQPixmap&, int sx=0, int sy=0, int sw=-1, int sh=-1); + void drawPixmap(const TQPoint&, const TQPixmap&, const TQRect&sr); + void drawPixmap(const TQPoint&, const TQPixmap&); + void drawPixmap(const TQRect&, const TQPixmap&); + void drawImage(int x, int y, const TQImage&, int sx = 0, int sy = 0, int sw = -1, int sh = -1, int conversionFlags = 0); + void drawImage(const TQPoint&, const TQImage&, const TQRect&sr, int conversionFlags = 0); + void drawImage(const TQPoint&, const TQImage&, int conversion_flags = 0); + void drawImage(const TQRect&, const TQImage&); + void drawTiledPixmap(int x, int y, int w, int h, const TQPixmap&, int sx=0, int sy=0); + void drawTiledPixmap(const TQRect&, const TQPixmap&, const TQPoint&); + void drawTiledPixmap(const TQRect&, const TQPixmap&); + //void drawPicture(const TQPicture&); + //void drawPicture(int x, int y, const TQPicture&); + //void drawPicture(const TQPoint&, const TQPicture&); + + void fillRect(int x, int y, int w, int h, const TQBrush&); + void fillRect(const TQRect&, const TQBrush&); + void eraseRect(int x, int y, int w, int h); + void eraseRect(const TQRect&); + + void drawText(int x, int y, const TQString&, int len = -1, TQPainter::TextDirection dir = TQPainter::Auto); + void drawText(const TQPoint&, const TQString&, int len = -1, TQPainter::TextDirection dir = TQPainter::Auto); + + void drawText(int x, int y, const TQString&, int pos, int len, TQPainter::TextDirection dir = TQPainter::Auto); + void drawText(const TQPoint&p, const TQString&, int pos, int len, TQPainter::TextDirection dir = TQPainter::Auto); + + void drawText(int x, int y, int w, int h, int flags, const TQString&, int len = -1, TQRect *br=0, TQTextParag **intern=0); + void drawText(const TQRect&, int flags, const TQString&, int len = -1, TQRect *br=0, TQTextParag **intern=0); + + void tqdrawTextItem(int x, int y, const TQTextItem&ti, int textflags = 0); + void tqdrawTextItem(const TQPoint& p, const TQTextItem&ti, int textflags = 0); + + TQRect boundingRect(int x, int y, int w, int h, int flags, const TQString&, int len = -1, TQTextParag **intern=0); + TQRect boundingRect(const TQRect&, int flags, const TQString&, int len = -1, TQTextParag **intern=0); + + int tabStops() const; + void setTabStops(int); + int *tabArray() const; + void setTabArray(int *); + +protected: + KisCanvasWidgetPainter *m_canvasWidgetPainter; + TQFont m_defaultFont; + TQPen m_defaultPen; + TQBrush m_defaultBrush; + TQColor m_defaultColor; + TQPoint m_defaultBrushOrigin; + TQWMatrix m_defaultWorldMatrix; +}; + +#endif // KIS_CANVAS_PAINTER_H_ + diff --git a/chalk/ui/kis_clipboard.cc b/chalk/ui/kis_clipboard.cc new file mode 100644 index 00000000..d52f5ec9 --- /dev/null +++ b/chalk/ui/kis_clipboard.cc @@ -0,0 +1,287 @@ +/* + * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include <tqapplication.h> +#include <tqclipboard.h> +#include <tqobject.h> +#include <tqimage.h> +#include <tqmessagebox.h> +#include <tqbuffer.h> +#include <kmultipledrag.h> +#include <klocale.h> + +#include "kdebug.h" + +#include "KoStore.h" +#include "KoStoreDrag.h" + +#include "kis_types.h" +#include "kis_paint_device.h" +#include "kis_config.h" +#include "kis_colorspace_factory_registry.h" +#include "kis_factory.h" +#include <kis_meta_registry.h> +#include "kis_clipboard.h" + +KisClipboard *KisClipboard::m_singleton = 0; + +KisClipboard::KisClipboard() +{ + Q_ASSERT(KisClipboard::m_singleton == 0); + KisClipboard::m_singleton = this; + + m_pushedClipboard = false; + m_hasClip = false; + m_clip = 0; + + // Check that we don't already have a clip ready + clipboardDataChanged(); + + // Make sure we are notified when clipboard changes + connect( TQApplication::tqclipboard(), TQT_SIGNAL( dataChanged() ), + this, TQT_SLOT( clipboardDataChanged() ) ); +} + +KisClipboard::~KisClipboard() +{ +} + +KisClipboard* KisClipboard::instance() +{ + if(KisClipboard::m_singleton == 0) + { + KisClipboard::m_singleton = new KisClipboard(); + Q_CHECK_PTR(KisClipboard::m_singleton); + } + return KisClipboard::m_singleton; +} + +void KisClipboard::setClip(KisPaintDeviceSP selection) +{ + m_clip = selection; + + if (!selection) + return; + + m_hasClip = true; + + // We'll create a store (ZIP format) in memory + TQBuffer buffer; + TQCString mimeType("application/x-chalk-selection"); + KoStore* store = KoStore::createStore( TQT_TQIODEVICE(&buffer), KoStore::Write, mimeType ); + Q_ASSERT( store ); + Q_ASSERT( !store->bad() ); + + // Layer data + if (store->open("layerdata")) { + if (!selection->write(store)) { + selection->disconnect(); + store->close(); + return; + } + store->close(); + } + + // ColorSpace id of layer data + if (store->open("colorspace")) { + TQString csName = selection->colorSpace()->id().id(); + store->write(csName.ascii(), strlen(csName.ascii())); + store->close(); + } + + if (selection->colorSpace()->getProfile()) { + KisAnnotationSP annotation = selection->colorSpace()->getProfile()->annotation(); + if (annotation) { + // save layer profile + if (store->open("profile.icc")) { + store->write(annotation->annotation()); + store->close(); + } + } + } + + delete store; + + // We also create a TQImage so we can interchange with other applications + TQImage qimg; + KisConfig cfg; + TQString monitorProfileName = cfg.monitorProfile(); + KisProfile * monitorProfile = KisMetaRegistry::instance()->csRegistry()->getProfileByName(monitorProfileName); + qimg = selection->convertToTQImage(monitorProfile); + + TQImageDrag *qimgDrag = new TQImageDrag(qimg); + KMultipleDrag *multiDrag = new KMultipleDrag(); + if ( !qimg.isNull() ) + multiDrag->addDragObject( qimgDrag ); + KoStoreDrag* storeDrag = new KoStoreDrag( mimeType, 0 ); + storeDrag->setEncodedData( buffer.buffer() ); + multiDrag->addDragObject( storeDrag ); + + + TQClipboard *cb = TQApplication::tqclipboard(); + cb->setData(multiDrag); + m_pushedClipboard = true; +} + +KisPaintDeviceSP KisClipboard::clip() +{ + TQClipboard *cb = TQApplication::tqclipboard(); + TQCString mimeType("application/x-chalk-selection"); + TQMimeSource *cbData = cb->data(); + + if(cbData && cbData->provides(mimeType)) + { + TQBuffer buffer(cbData->tqencodedData(mimeType)); + KoStore* store = KoStore::createStore( TQT_TQIODEVICE(&buffer), KoStore::Read, mimeType ); + KisProfile *profile=0; + + if (store->hasFile("profile.icc")) { + TQByteArray data; + store->open("profile.icc"); + data = store->read(store->size()); + store->close(); + profile = new KisProfile(data); + } + + TQString csName; + // ColorSpace id of layer data + if (store->hasFile("colorspace")) { + store->open("colorspace"); + csName = TQString(store->read(store->size())); + store->close(); + } + + KisColorSpace *cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID(csName, ""), profile); + + m_clip = new KisPaintDevice(cs, "clip"); + + if (store->hasFile("layerdata")) { + store->open("layerdata"); + m_clip->read(store); + store->close(); + } + delete store; + } + else + { + TQImage qimg = cb->image(); + + if (qimg.isNull()) + return 0; + + KisConfig cfg; + + TQ_UINT32 behaviour = cfg.pasteBehaviour(); + + if(behaviour==2) + { + // Ask user each time + behaviour = TQMessageBox::question(0,i18n("Pasting data from simple source"),i18n("The image data you are trying to paste has no colour profile information.\n\nOn the web and in simple applications the data are supposed to be in sRGB color format.\nImporting as web will show it as it is supposed to look.\nMost monitors are not perfect though so if you made the image yourself\nyou might want to import it as it looked on you monitor.\n\nHow do you want to interpret these data?"),i18n("As &Web"),i18n("As on &Monitor")); + } + + KisColorSpace * cs; + TQString profileName(""); + if(behaviour==1) + profileName = cfg.monitorProfile(); + + cs = KisMetaRegistry::instance()->csRegistry() ->getColorSpace(KisID("RGBA",""), profileName); + m_clip = new KisPaintDevice(cs, "from paste"); + Q_CHECK_PTR(m_clip); + m_clip->convertFromTQImage(qimg, profileName); + } + + return m_clip; +} + +void KisClipboard::clipboardDataChanged() +{ + if (!m_pushedClipboard) { + m_hasClip = false; + TQClipboard *cb = TQApplication::tqclipboard(); + TQImage qimg = cb->image(); + TQMimeSource *cbData = cb->data(); + TQCString mimeType("application/x-chalk-selection"); + + if(cbData && cbData->provides(mimeType)) + m_hasClip = true; + + if (!qimg.isNull()) + m_hasClip = true; + } + + m_pushedClipboard = false; +} + + +bool KisClipboard::hasClip() +{ + return m_hasClip; +} + +TQSize KisClipboard::clipSize() +{ + + TQClipboard *cb = TQApplication::tqclipboard(); + TQCString mimeType("application/x-chalk-selection"); + TQMimeSource *cbData = cb->data(); + + KisPaintDeviceSP clip; + + if(cbData && cbData->provides(mimeType)) { + + TQBuffer buffer(cbData->tqencodedData(mimeType)); + KoStore* store = KoStore::createStore( TQT_TQIODEVICE(&buffer), KoStore::Read, mimeType ); + KisProfile *profile=0; + + if (store->hasFile("profile.icc")) { + TQByteArray data; + store->open("profile.icc"); + data = store->read(store->size()); + store->close(); + profile = new KisProfile(data); + } + + TQString csName; + // ColorSpace id of layer data + if (store->hasFile("colorspace")) { + store->open("colorspace"); + csName = TQString(store->read(store->size())); + store->close(); + } + + KisColorSpace *cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID(csName, ""), profile); + + clip = new KisPaintDevice(cs, "clip"); + + if (store->hasFile("layerdata")) { + store->open("layerdata"); + clip->read(store); + store->close(); + } + delete store; + + return clip->exactBounds().size(); + } + else { + TQImage qimg = cb->image(); + return qimg.size(); + } +; + +} + +#include "kis_clipboard.moc" diff --git a/chalk/ui/kis_clipboard.h b/chalk/ui/kis_clipboard.h new file mode 100644 index 00000000..020240e6 --- /dev/null +++ b/chalk/ui/kis_clipboard.h @@ -0,0 +1,80 @@ +/* + * kis_clipboard.h - part of Krayon + * + * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __KIS_CLIPBOARD_H_ +#define __KIS_CLIPBOARD_H_ + + +#include <tqsize.h> +#include "kis_types.h" + +class TQImage; + +/** + * The Chalk clipboard is a clipboard that can store paint devices + * instead of just qimage's. + */ +class KisClipboard : public TQObject { + + Q_OBJECT + TQ_OBJECT + +public: + + virtual ~KisClipboard(); + + static KisClipboard* instance(); + + /** + * Sets the clipboard to the contents of the specified paint device; also + * set the system clipboard to a TQImage representation of the specified + * paint device. + */ + void setClip(KisPaintDeviceSP layer); + + /** + * Get the contents of the clipboard in the form of a paint device. + */ + KisPaintDeviceSP clip(); + + bool hasClip(); + + TQSize clipSize(); + +private slots: + + void clipboardDataChanged(); +private: + + KisClipboard(); + KisClipboard(const KisClipboard &); + KisClipboard operator=(const KisClipboard &); + + static KisClipboard * m_singleton; + + KisPaintDeviceSP m_clip; + bool m_hasClip; + + bool m_pushedClipboard; + + +}; + +#endif // __KIS_CLIPBOARD_H_ diff --git a/chalk/ui/kis_cmb_composite.cc b/chalk/ui/kis_cmb_composite.cc new file mode 100644 index 00000000..54c4b643 --- /dev/null +++ b/chalk/ui/kis_cmb_composite.cc @@ -0,0 +1,88 @@ +/* + * kis_cmb_composite.cc - part of KImageShop/Krayon/Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <tqcombobox.h> + +#include <klocale.h> +#include <kdebug.h> + +#include "kis_cmb_composite.h" + +KisCmbComposite::KisCmbComposite(TQWidget * tqparent, const char * name) + : super( false, tqparent, name ) +{ + connect(this, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotOpActivated(int))); + connect(this, TQT_SIGNAL(highlighted(int)), this, TQT_SLOT(slotOpHighlighted(int))); +} + +KisCmbComposite::~KisCmbComposite() +{ +} + +void KisCmbComposite::setCompositeOpList(const KisCompositeOpList & list) +{ + super::clear(); + m_list = list; + KisCompositeOpList::iterator it; + for( it = m_list.begin(); it != m_list.end(); ++it ) + insertItem((*it).id().name()); +} + +KisCompositeOp KisCmbComposite::currentItem() const +{ + TQ_UINT32 i = super::currentItem(); + if (i > m_list.count()) return KisCompositeOp(); + + return m_list[i]; +} + +void KisCmbComposite::setCurrentItem(const KisCompositeOp& op) +{ + if (m_list.tqfind(op) != m_list.end()) { + super::setCurrentText(op.id().name()); + } +} + +void KisCmbComposite::setCurrentText(const TQString & s) +{ + KisCompositeOpList::iterator it; + for( it = m_list.begin(); it != m_list.end(); ++it ) + if ((*it).id().id() == s) { + super::setCurrentText((*it).id().name()); + } +} + +void KisCmbComposite::slotOpActivated(int i) +{ + if ((TQ_UINT32)i > m_list.count()) return; + + emit activated(m_list[i]); +} + +void KisCmbComposite::slotOpHighlighted(int i) +{ + if ((TQ_UINT32)i > m_list.count()) return; + + emit highlighted(m_list[i]); +} + + +#include "kis_cmb_composite.moc" + diff --git a/chalk/ui/kis_cmb_composite.h b/chalk/ui/kis_cmb_composite.h new file mode 100644 index 00000000..ef5df0e6 --- /dev/null +++ b/chalk/ui/kis_cmb_composite.h @@ -0,0 +1,71 @@ +/* + * kis_cmb_composite.h - part of KImageShop/Krayon/Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_CMB_COMPOSITE_H_ +#define KIS_CMB_COMPOSITE_H_ + +#include <koffice_export.h> +#include "tqcombobox.h" +#include "kis_composite_op.h" + +/** + * A combobox filled with the various composition strategies defined in kis_global. + * + * XXX: devise some kind of capabilities database for the various colour strategies + * + * enum constant Description CMYK RGBA GRAYA + * 1 COMPOSITE_OVER Over X - X + * + * But that's for later... + */ + +class KRITAUI_EXPORT KisCmbComposite : public TQComboBox +{ + typedef TQComboBox super; + + Q_OBJECT + TQ_OBJECT + + public: + + KisCmbComposite(TQWidget * tqparent = 0, const char * name = 0 ); + virtual ~KisCmbComposite(); + + KisCompositeOp currentItem() const; + + void setCompositeOpList(const KisCompositeOpList& list); + void setCurrentItem(const KisCompositeOp& op); + void setCurrentText(const TQString & s); + +signals: + + void activated(const KisCompositeOp &); + void highlighted(const KisCompositeOp &); + +private slots: + + void slotOpActivated(int i); + void slotOpHighlighted(int i); + +private: + KisCompositeOpList m_list; +}; + +#endif diff --git a/chalk/ui/kis_cmb_idlist.cc b/chalk/ui/kis_cmb_idlist.cc new file mode 100644 index 00000000..bdd6f09b --- /dev/null +++ b/chalk/ui/kis_cmb_idlist.cc @@ -0,0 +1,97 @@ +/* + * kis_cmb_idlist.cc - part of KImageShop/Krayon/Chalk + * + * Copyright (c) 2005 Boudewijn Rempt (boud@valdyas.org) + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <tqcombobox.h> + +#include <klocale.h> +#include <kdebug.h> + +#include "kis_id.h" +#include "kis_cmb_idlist.h" + +KisCmbIDList::KisCmbIDList(TQWidget * tqparent, const char * name) + : super( false, tqparent, name ) +{ + connect(this, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotIDActivated(int))); + connect(this, TQT_SIGNAL(highlighted(int)), this, TQT_SLOT(slotIDHighlighted(int))); +} + +KisCmbIDList::~KisCmbIDList() +{ +} + + +void KisCmbIDList::setIDList(const KisIDList & list) +{ + m_list = list; + KisIDList::iterator it; + for( it = m_list.begin(); it != m_list.end(); ++it ) + insertItem((*it).name()); +} + + +KisID KisCmbIDList::currentItem() const +{ + TQ_UINT32 i = super::currentItem(); + if (i > m_list.count()) return KisID(); + + return m_list[i]; +} + +void KisCmbIDList::setCurrent(const KisID id) +{ + if (m_list.tqfind(id) != m_list.end()) + super::setCurrentText(id.name()); + else { + m_list.push_back(id); + insertItem(id.name()); + super::setCurrentText(id.name()); + } +} + +void KisCmbIDList::setCurrentText(const TQString & s) +{ + KisIDList::iterator it; + for( it = m_list.begin(); it != m_list.end(); ++it ) + if ((*it).id() == s) { + super::setCurrentText((*it).name()); + } +} + +void KisCmbIDList::slotIDActivated(int i) +{ + if ((uint)i > m_list.count()) return; + + emit activated(m_list[i]); + +} + +void KisCmbIDList::slotIDHighlighted(int i) +{ + if ((uint)i > m_list.count()) return; + + emit highlighted(m_list[i]); + +} + + + +#include "kis_cmb_idlist.moc" + diff --git a/chalk/ui/kis_cmb_idlist.h b/chalk/ui/kis_cmb_idlist.h new file mode 100644 index 00000000..2665c8f8 --- /dev/null +++ b/chalk/ui/kis_cmb_idlist.h @@ -0,0 +1,68 @@ +/* + * kis_cmb_imagetype.h - part of KImageShop/Krayon/Chalk + * + * Copyright (c) 2005 Boudewijn Rempt (boud@valdyas.org) + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_CMB_IDLIST_H_ +#define KIS_CMB_IDLIST_H_ + +#include "tqcombobox.h" + +#include "kis_id.h" + +/** + * A combobox that is associated with a list of KisID's. The + * descriptive (i18n'ed) text is displayed, but the various + * signals return a KisID. + */ +class KisCmbIDList : public TQComboBox +{ + typedef TQComboBox super; + + Q_OBJECT + TQ_OBJECT + +public: + + KisCmbIDList(TQWidget * tqparent = 0, const char * name = 0 ); + virtual ~KisCmbIDList(); + + +public: + void setIDList(const KisIDList & list); + void setCurrent(const KisID id); + void setCurrentText(const TQString & s); + + KisID currentItem() const; + +signals: + + void activated(const KisID &); + void highlighted(const KisID &); + +private slots: + + void slotIDActivated(int i); + void slotIDHighlighted(int i); + +private: + + KisIDList m_list; + +}; +#endif diff --git a/chalk/ui/kis_color_cup.cc b/chalk/ui/kis_color_cup.cc new file mode 100644 index 00000000..44a9699b --- /dev/null +++ b/chalk/ui/kis_color_cup.cc @@ -0,0 +1,118 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 1999 Matthias Elter (me@kde.org) + * Copyright (c) 2001-2002 Igor Jansen (rm@kde.org) + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include <tqpushbutton.h> +#include <tqapplication.h> +#include <tqclipboard.h> +#include <tqcolor.h> +#include <tqdrawutil.h> +#include <tqhbox.h> +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqpainter.h> +#include <tqspinbox.h> +#include <tqstyle.h> +#include <tqtooltip.h> +#include <tqwidget.h> +#include <tqframe.h> + +#include <kcolordialog.h> +#include <klocale.h> +#include <knuminput.h> +#include <koFrameButton.h> + +#include <kis_canvas_subject.h> +#include <kis_color.h> +#include <kis_color_cup.h> + +KisColorPopup::KisColorPopup(TQColor c, TQWidget * tqparent, const char * name) + : TQFrame(tqparent, name, WType_Popup | WStyle_Customize | WStyle_NoBorder) +{ + m_color = c; + setMargin(4); + setFocusPolicy(TQ_StrongFocus); + TQHBoxLayout * l = new TQHBoxLayout(this); + l->add(m_khsSelector = new KHSSelector(this)); + m_khsSelector->setMinimumSize(140, 7); + l->add(m_valueSelector = new KValueSelector(this)); + m_valueSelector->setMinimumSize(26, 70); + m_khsSelector->show(); + m_valueSelector->show(); + +} + +KisColorCup::KisColorCup(TQWidget * tqparent, const char * name) + : TQPushButton(tqparent, name) +{ + m_color = TQt::black; + m_popup = new KisColorPopup(m_color, this, "colorpopup"); + connect(this, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotClicked())); + connect(m_popup, TQT_SIGNAL(changed( const TQColor &)), this, TQT_SLOT(setColor(const TQColor &))); +} + +void KisColorCup::setColor(const TQColor & c) +{ + m_color = c; + emit changed(c); +} + +void KisColorCup::slotClicked() +{ +// m_popup->move(this->mapToGlobal( this->rect().topRight() ) ); +// m_popup->show(); + emit changed(m_color); +} + +TQSize KisColorCup::tqsizeHint() const +{ + return tqstyle().tqsizeFromContents(TQStyle::CT_PushButton, this, TQSize(24, 24)). + expandedTo(TQApplication::globalStrut()); +} + +void KisColorCup::drawButtonLabel( TQPainter *painter ) +{ + int x, y, w, h; + TQRect r = tqstyle().subRect( TQStyle::SR_PushButtonContents, this ); + r.rect(&x, &y, &w, &h); + + int margin = 2; //tqstyle().tqpixelMetric( TQStyle::PM_ButtonMargin, this ); + x += margin; + y += margin; + w -= 2*margin; + h -= 2*margin; + + if (isOn() || isDown()) { + x += tqstyle().tqpixelMetric( TQStyle::PM_ButtonShiftHorizontal, this ); + y += tqstyle().tqpixelMetric( TQStyle::PM_ButtonShiftVertical, this ); + } + + qDrawShadePanel( painter, x, y, w, h, tqcolorGroup(), true, 1, NULL); + if ( m_color.isValid() ) + painter->fillRect( x+1, y+1, w-2, h-2, m_color ); + + if ( hasFocus() ) { + TQRect focusRect = tqstyle().subRect( TQStyle::SR_PushButtonFocusRect, this ); + tqstyle().tqdrawPrimitive( TQStyle::PE_FocusRect, painter, focusRect, tqcolorGroup() ); + } + +} + +#include "kis_color_cup.moc" diff --git a/chalk/ui/kis_color_cup.h b/chalk/ui/kis_color_cup.h new file mode 100644 index 00000000..7a59837a --- /dev/null +++ b/chalk/ui/kis_color_cup.h @@ -0,0 +1,96 @@ +/* This file is part of the KDE project + * + * Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_COLOR_CUP_H +#define KIS_COLOR_CUP_H + +#include <tqpushbutton.h> +#include <tqcolor.h> +#include <tqframe.h> + +#include <koffice_export.h> + +class TQSize; +class TQPainter; +class TQWidget; +class KHSSelector; +class KValueSelector; + +class KisColorPopup : public TQFrame { + + Q_OBJECT + TQ_OBJECT + +public: + + KisColorPopup(TQColor color, TQWidget * w, const char * name); + virtual ~KisColorPopup() {}; + +signals: + + void changed(const TQColor &); + +private: + + KHSSelector * m_khsSelector; + KValueSelector * m_valueSelector; + + TQColor m_color; +}; + +class KRITAUI_EXPORT KisColorCup : public TQPushButton { + + Q_OBJECT + TQ_OBJECT + +public: + + KisColorCup(TQWidget * tqparent, const char * name = 0); + + virtual ~KisColorCup() {}; + + TQColor color() { return m_color; }; + +signals: + + void changed(const TQColor &); + +public: + + TQSize tqsizeHint() const; + +public slots: + + void setColor(const TQColor & c); + + +private slots: + + void slotClicked(); + +protected: + + virtual void drawButtonLabel( TQPainter *p ); + +private: + + KisColorPopup * m_popup; + TQColor m_color; +}; + +#endif diff --git a/chalk/ui/kis_config.cc b/chalk/ui/kis_config.cc new file mode 100644 index 00000000..6d07790b --- /dev/null +++ b/chalk/ui/kis_config.cc @@ -0,0 +1,442 @@ +/* + * Copyright (c) 2002 Patrick Julien <freak@codepimps.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include <limits.h> + +#include <kglobalsettings.h> +#include <kconfig.h> +#include <kglobal.h> +#include <kdebug.h> +#include <config.h> + +#include LCMS_HEADER + +#include "kis_global.h" +#include "kis_config.h" + +namespace { + const double IMG_DEFAULT_RESOLUTION = 100.0; + const TQ_INT32 IMG_DEFAULT_WIDTH = 512; + const TQ_INT32 IMG_DEFAULT_HEIGHT = 512; + const enumCursorStyle DEFAULT_CURSOR_STYLE = CURSOR_STYLE_OUTLINE; + const TQ_INT32 DEFAULT_MAX_THREADS = 4; + const TQ_INT32 DEFAULT_MAX_TILES_MEM = 500; // 8192 kilobytes given 64x64 tiles with 32bpp + const TQ_INT32 DEFAULT_SWAPPINESS = 100; + const TQ_INT32 DEFAULT_PRESSURE_CORRECTION = 50; + const TQ_INT32 DEFAULT_DOCKABILITY = 0; + const TQ_INT32 DEFAULT_UNDO_LIMIT = 50; +} + +KisConfig::KisConfig() +{ + + m_cfg = KGlobal::config(); + if (!m_cfg) { + // Allow unit tests to test parts of the code without having to run the + // full application. + m_cfg = new KConfig(); + } + m_cfg->setGroup(""); +} + +KisConfig::~KisConfig() +{ + m_cfg->sync(); +} + + +bool KisConfig::fixDockerWidth() const +{ + return m_cfg->readBoolEntry("fixDockerWidth", true); +} + +void KisConfig::setFixedDockerWidth(bool fix) +{ + m_cfg->writeEntry("fixDockerWidth", fix); +} + +bool KisConfig::undoEnabled() const +{ + return m_cfg->readBoolEntry("undoEnabled", true); +} + +void KisConfig::setUndoEnabled(bool undo) +{ + m_cfg->writeEntry("undoEnabled", undo); +} + + +TQ_INT32 KisConfig::defUndoLimit() const +{ + return m_cfg->readNumEntry("undolimit", DEFAULT_UNDO_LIMIT); +} + +void KisConfig::defUndoLimit(TQ_INT32 limit) +{ + m_cfg->writeEntry("undolimit", limit); +} + +TQ_INT32 KisConfig::defImgWidth() const +{ + return m_cfg->readNumEntry("imgWidthDef", IMG_DEFAULT_WIDTH); +} + +TQ_INT32 KisConfig::defImgHeight() const +{ + return m_cfg->readNumEntry("imgHeightDef", IMG_DEFAULT_HEIGHT); +} + +double KisConfig::defImgResolution() const +{ + return m_cfg->readDoubleNumEntry("imgResolutionDef", IMG_DEFAULT_RESOLUTION); +} + +void KisConfig::defImgWidth(TQ_INT32 width) +{ + m_cfg->writeEntry("imgWidthDef", width); +} + +void KisConfig::defImgHeight(TQ_INT32 height) +{ + m_cfg->writeEntry("imgHeightDef", height); +} + +void KisConfig::defImgResolution(double res) +{ + m_cfg->writeEntry("imgResolutionDef", res); +} + +enumCursorStyle KisConfig::cursorStyle() const +{ + return (enumCursorStyle) m_cfg->readNumEntry("cursorStyleDef", DEFAULT_CURSOR_STYLE); +} + +enumCursorStyle KisConfig::getDefaultCursorStyle() const +{ + return DEFAULT_CURSOR_STYLE; +} + +void KisConfig::setCursorStyle(enumCursorStyle style) +{ + m_cfg->writeEntry("cursorStyleDef", style); +} + + +TQString KisConfig::monitorProfile() const +{ + return m_cfg->readEntry("monitorProfile", ""); +} + +void KisConfig::setMonitorProfile(TQString monitorProfile) +{ + m_cfg->writeEntry("monitorProfile", monitorProfile); +} + + +TQString KisConfig::workingColorSpace() const +{ + return m_cfg->readEntry("workingColorSpace", "RGBA"); +} + +void KisConfig::setWorkingColorSpace(TQString workingColorSpace) +{ + m_cfg->writeEntry(workingColorSpace, workingColorSpace); +} + + +TQString KisConfig::printerColorSpace() const +{ + return m_cfg->readEntry("printerColorSpace", "CMYK"); +} + +void KisConfig::setPrinterColorSpace(TQString printerColorSpace) +{ + m_cfg->writeEntry("printerColorSpace", printerColorSpace); +} + + +TQString KisConfig::printerProfile() const +{ + return m_cfg->readEntry("printerProfile", ""); +} + +void KisConfig::setPrinterProfile(TQString printerProfile) +{ + m_cfg->writeEntry("printerProfile", printerProfile); +} + + +bool KisConfig::useBlackPointCompensation() const +{ + return m_cfg->readBoolEntry("useBlackPointCompensation", false); +} + +void KisConfig::setUseBlackPointCompensation(bool useBlackPointCompensation) +{ + m_cfg->writeEntry("useBlackPointCompensation", useBlackPointCompensation); +} + + +bool KisConfig::showRulers() const +{ + return m_cfg->readBoolEntry("showrulers", false); +} + +void KisConfig::setShowRulers(bool rulers) +{ + m_cfg->writeEntry("showrulers", rulers); +} + + +TQ_INT32 KisConfig::pasteBehaviour() const +{ + return m_cfg->readNumEntry("pasteBehaviour", 2); +} + +void KisConfig::setPasteBehaviour(TQ_INT32 renderIntent) +{ + m_cfg->writeEntry("pasteBehaviour", renderIntent); +} + + +TQ_INT32 KisConfig::renderIntent() const +{ + return m_cfg->readNumEntry("renderIntent", INTENT_PERCEPTUAL); +} + +void KisConfig::setRenderIntent(TQ_INT32 renderIntent) +{ + m_cfg->writeEntry("renderIntent", renderIntent); +} + +bool KisConfig::useOpenGL() const +{ + return m_cfg->readBoolEntry("useOpenGL", false); +} + +void KisConfig::setUseOpenGL(bool useOpenGL) +{ + m_cfg->writeEntry("useOpenGL", useOpenGL); +} + +bool KisConfig::useOpenGLShaders() const +{ + return m_cfg->readBoolEntry("useOpenGLShaders", false); +} + +void KisConfig::setUseOpenGLShaders(bool useOpenGLShaders) +{ + m_cfg->writeEntry("useOpenGLShaders", useOpenGLShaders); +} + +TQ_INT32 KisConfig::maxNumberOfThreads() +{ + return m_cfg->readNumEntry("maxthreads", DEFAULT_MAX_THREADS); +} + +void KisConfig::setMaxNumberOfThreads(TQ_INT32 maxThreads) +{ + m_cfg->writeEntry("maxthreads", maxThreads); +} + +TQ_INT32 KisConfig::maxTilesInMem() const +{ + return m_cfg->readNumEntry("maxtilesinmem", DEFAULT_MAX_TILES_MEM); +} + +void KisConfig::setMaxTilesInMem(TQ_INT32 tiles) +{ + m_cfg->writeEntry("maxtilesinmem", tiles); +} + +TQ_INT32 KisConfig::swappiness() const +{ + return m_cfg->readNumEntry("swappiness", DEFAULT_SWAPPINESS); +} + +void KisConfig::setSwappiness(TQ_INT32 swappiness) +{ + m_cfg->writeEntry("swappiness", swappiness); +} + +TQ_INT32 KisConfig::getPressureCorrection() +{ + return m_cfg->readNumEntry( "pressurecorrection", DEFAULT_PRESSURE_CORRECTION ); +} + +void KisConfig::setPressureCorrection( TQ_INT32 correction ) +{ + m_cfg->writeEntry( "pressurecorrection", correction ); +} + +TQ_INT32 KisConfig::getDefaultPressureCorrection() +{ + return DEFAULT_PRESSURE_CORRECTION; +} + +bool KisConfig::tabletDeviceEnabled(const TQString& tabletDeviceName) const +{ + return m_cfg->readBoolEntry("TabletDevice" + tabletDeviceName + "Enabled", false); +} + +void KisConfig::setTabletDeviceEnabled(const TQString& tabletDeviceName, bool enabled) +{ + m_cfg->writeEntry("TabletDevice" + tabletDeviceName + "Enabled", enabled); +} + +TQ_INT32 KisConfig::tabletDeviceAxis(const TQString& tabletDeviceName, const TQString& axisName, TQ_INT32 defaultAxis) const +{ + return m_cfg->readNumEntry("TabletDevice" + tabletDeviceName + axisName, defaultAxis); +} + +void KisConfig::setTabletDeviceAxis(const TQString& tabletDeviceName, const TQString& axisName, TQ_INT32 axis) const +{ + m_cfg->writeEntry("TabletDevice" + tabletDeviceName + axisName, axis); +} + +void KisConfig::setDockability( TQ_INT32 dockability ) +{ + m_cfg->writeEntry( "palettesdockability", dockability ); +} + +TQ_INT32 KisConfig::dockability() +{ + return m_cfg->readNumEntry("palettesdockability", DEFAULT_DOCKABILITY); +} + +TQ_INT32 KisConfig::getDefaultDockability() +{ + return DEFAULT_DOCKABILITY; +} + +float KisConfig::dockerFontSize() +{ + return (float) m_cfg->readNumEntry("palettefontsize", (int)getDefaultDockerFontSize()); +} + +float KisConfig::getDefaultDockerFontSize() +{ + float ps = TQMIN(9, KGlobalSettings::generalFont().pointSize() * 0.8); + if (ps < 6) ps = 6; + return ps; +} + +void KisConfig::setDockerFontSize(float size) +{ + m_cfg->writeEntry("palettefontsize", size); +} + +TQ_UINT32 KisConfig::getGridMainStyle() +{ + TQ_UINT32 v = m_cfg->readNumEntry("gridmainstyle", 0); + if (v > 2) + v = 2; + return v; +} + +void KisConfig::setGridMainStyle(TQ_UINT32 v) +{ + m_cfg->writeEntry("gridmainstyle", v); +} + +TQ_UINT32 KisConfig::getGridSubdivisionStyle() +{ + TQ_UINT32 v = m_cfg->readNumEntry("gridsubdivisionstyle", 1); + if (v > 2) v = 2; + return v; +} + +void KisConfig::setGridSubdivisionStyle(TQ_UINT32 v) +{ + m_cfg->writeEntry("gridsubdivisionstyle", v); +} + +TQColor KisConfig::getGridMainColor() +{ + return m_cfg->readColorEntry("gridmaincolor", new TQColor(99,99,99)); +} + +void KisConfig::setGridMainColor(TQColor v) +{ + m_cfg->writeEntry("gridmaincolor", v); +} + +TQColor KisConfig::getGridSubdivisionColor() +{ + return m_cfg->readColorEntry("gridsubdivisioncolor", new TQColor(150,150,150)); +} + +void KisConfig::setGridSubdivisionColor(TQColor v) +{ + m_cfg->writeEntry("gridsubdivisioncolor", v); +} + +TQ_UINT32 KisConfig::getGridHSpacing() +{ + TQ_INT32 v = m_cfg->readNumEntry("gridhspacing", 10); + return (TQ_UINT32)TQMAX(1, v ); +} + +void KisConfig::setGridHSpacing(TQ_UINT32 v) +{ + m_cfg->writeEntry("gridhspacing", v); +} + +TQ_UINT32 KisConfig::getGridVSpacing() +{ + TQ_INT32 v = m_cfg->readNumEntry("gridvspacing", 10); + return (TQ_UINT32)TQMAX(1, v ); +} + +void KisConfig::setGridVSpacing(TQ_UINT32 v) +{ + m_cfg->writeEntry("gridvspacing", v); +} + +TQ_UINT32 KisConfig::getGridSubdivisions() +{ + TQ_INT32 v = m_cfg->readNumEntry("gridsubsivisons", 2); + return (TQ_UINT32)TQMAX(1, v ); +} + +void KisConfig::setGridSubdivisions(TQ_UINT32 v) +{ + return m_cfg->writeEntry("gridsubsivisons", v); +} + +TQ_UINT32 KisConfig::getGridOffsetX() +{ + TQ_INT32 v = m_cfg->readNumEntry("gridoffsetx", 0); + return (TQ_UINT32)TQMAX(0, v ); +} + +void KisConfig::setGridOffsetX(TQ_UINT32 v) +{ + m_cfg->writeEntry("gridoffsetx", v); +} + +TQ_UINT32 KisConfig::getGridOffsetY() +{ + TQ_INT32 v = m_cfg->readNumEntry("gridoffsety", 0); + return (TQ_UINT32)TQMAX(0, v ); +} + +void KisConfig::setGridOffsetY(TQ_UINT32 v) +{ + m_cfg->writeEntry("gridoffsety", v); +} + diff --git a/chalk/ui/kis_config.h b/chalk/ui/kis_config.h new file mode 100644 index 00000000..4fe971df --- /dev/null +++ b/chalk/ui/kis_config.h @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2002 Patrick Julien <freak@codepimps.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_CONFIG_H_ +#define KIS_CONFIG_H_ + +#include "kis_global.h" +#include "koffice_export.h" + +class KRITACORE_EXPORT KisConfig { +public: + KisConfig(); + ~KisConfig(); + + bool fixDockerWidth() const; + void setFixedDockerWidth(bool fix); + + bool undoEnabled() const; + void setUndoEnabled(bool undo); + + TQ_INT32 defUndoLimit() const; + void defUndoLimit(TQ_INT32 limit); + + TQ_INT32 defImgWidth() const; + void defImgWidth(TQ_INT32 width); + + TQ_INT32 defImgHeight() const; + void defImgHeight(TQ_INT32 height); + + double defImgResolution() const; + void defImgResolution(double res); + + enumCursorStyle cursorStyle() const; + enumCursorStyle getDefaultCursorStyle() const; + void setCursorStyle(enumCursorStyle style); + + TQString monitorProfile() const; + void setMonitorProfile(TQString monitorProfile); + + TQString workingColorSpace() const; + void setWorkingColorSpace(TQString workingColorSpace); + + TQString importProfile() const; + void setImportProfile(TQString importProfile); + + TQString printerColorSpace() const; + void setPrinterColorSpace(TQString printerColorSpace); + + TQString printerProfile() const; + void setPrinterProfile(TQString printerProfile); + + bool useBlackPointCompensation() const; + void setUseBlackPointCompensation(bool useBlackPointCompensation); + + bool showRulers() const; + void setShowRulers(bool rulers); + + TQ_INT32 pasteBehaviour() const; + void setPasteBehaviour(TQ_INT32 behaviour); + + TQ_INT32 renderIntent() const; + void setRenderIntent(TQ_INT32 renderIntent); + + bool useOpenGL() const; + void setUseOpenGL(bool useOpenGL); + + bool useOpenGLShaders() const; + void setUseOpenGLShaders(bool useOpenGLShaders); + + TQ_INT32 maxNumberOfThreads(); + void setMaxNumberOfThreads(TQ_INT32 numberOfThreads); + + /// Maximum tiles in memory (this is a guideline, not absolute) + TQ_INT32 maxTilesInMem() const; + void setMaxTilesInMem(TQ_INT32 tiles); + + /// Number of tiles that will be swapped at once. The higher, the more swapped, but more + /// chance that it will become slow + TQ_INT32 swappiness() const; + void setSwappiness(TQ_INT32 swappiness); + + TQ_INT32 getPressureCorrection(); + void setPressureCorrection( TQ_INT32 correction); + TQ_INT32 getDefaultPressureCorrection(); + + bool tabletDeviceEnabled(const TQString& tabletDeviceName) const; + void setTabletDeviceEnabled(const TQString& tabletDeviceName, bool enabled); + + TQ_INT32 tabletDeviceAxis(const TQString& tabletDeviceName, const TQString& axisName, TQ_INT32 defaultAxis) const; + void setTabletDeviceAxis(const TQString& tabletDeviceName, const TQString& axisName, TQ_INT32 axis) const; + + TQ_INT32 dockability(); + TQ_INT32 getDefaultDockability(); + void setDockability( TQ_INT32 dockability); + + float dockerFontSize(); + float getDefaultDockerFontSize(); + void setDockerFontSize(float); + + + TQ_UINT32 getGridMainStyle(); + void setGridMainStyle(TQ_UINT32 v); + TQ_UINT32 getGridSubdivisionStyle(); + void setGridSubdivisionStyle(TQ_UINT32 v); + TQColor getGridMainColor(); + void setGridMainColor(TQColor v); + TQColor getGridSubdivisionColor(); + void setGridSubdivisionColor(TQColor v); + TQ_UINT32 getGridHSpacing(); + void setGridHSpacing(TQ_UINT32 v); + TQ_UINT32 getGridVSpacing(); + void setGridVSpacing(TQ_UINT32 v); + TQ_UINT32 getGridSubdivisions(); + void setGridSubdivisions(TQ_UINT32 v); + TQ_UINT32 getGridOffsetX(); + void setGridOffsetX(TQ_UINT32 v); + TQ_UINT32 getGridOffsetY(); + void setGridOffsetY(TQ_UINT32 v); + + +private: + KisConfig(const KisConfig&); + KisConfig& operator=(const KisConfig&); + +private: + mutable KConfig *m_cfg; +}; + +#endif // KIS_CONFIG_H_ diff --git a/chalk/ui/kis_controlframe.cc b/chalk/ui/kis_controlframe.cc new file mode 100644 index 00000000..29b9aa8b --- /dev/null +++ b/chalk/ui/kis_controlframe.cc @@ -0,0 +1,343 @@ +/* + * kis_controlframe.cc - part of Chalk + * + * Copyright (c) 1999 Matthias Elter <elter@kde.org> + * Copyright (c) 2003 Patrick Julien <freak@codepimps.org> + * Copyright (c) 2004 Sven Langkamp <longamp@reallygood.de> + * + * 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 2 of the License, 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.g + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <stdlib.h> + +#include <tqapplication.h> +#include <tqlayout.h> +#include <tqtabwidget.h> +#include <tqframe.h> +#include <tqwidget.h> +#include <tqevent.h> + +#include <ktoolbar.h> +#include <kmainwindow.h> +#include <kglobalsettings.h> +#include <kstandarddirs.h> +#include <kdebug.h> +#include <klocale.h> +#include <koFrameButton.h> +#include <kactioncollection.h> + +#include "kis_resourceserver.h" +#include "kis_controlframe.h" +#include "kis_resource_mediator.h" +#include "kis_itemchooser.h" +#include "kis_pattern_chooser.h" +#include "kis_gradient_chooser.h" +#include "kis_icon_item.h" +#include "kis_iconwidget.h" +#include "kis_brush.h" +#include "kis_pattern.h" +#include "kis_gradient.h" +#include "kis_brush_chooser.h" +#include "kis_view.h" +#include "kis_autobrush.h" +#include "kis_autogradient.h" +#include "kis_config.h" +#include "kis_paintop_box.h" +#include "kis_custom_brush.h" +#include "kis_custom_pattern.h" +#ifdef HAVE_TEXT_BRUSH +#include "kis_text_brush.h" +#endif +KisPopupFrame::KisPopupFrame(TQWidget * tqparent, const char* name) + : TQPopupMenu(tqparent, name) +{ + setFocusPolicy(TQ_StrongFocus); +} + +void KisPopupFrame::keyPressEvent(TQKeyEvent * e) +{ + if (e->key()== TQt::Key_Escape) + { + hide(); + e->accept(); + } + else { + e->ignore(); + } +} + + +KisControlFrame::KisControlFrame( KMainWindow * /*window*/, KisView * view, const char* name ) + : TQObject(view, name) + //: KToolBar ( window, TQt::DockTop, false, name, true, true ) + , m_view(view) + , m_brushWidget(0) + , m_patternWidget(0) + , m_gradientWidget(0) + , m_brushChooserPopup(0) + , m_patternChooserPopup(0) + , m_gradientChooserPopup(0) + , m_brushMediator(0) + , m_patternMediator(0) + , m_gradientMediator(0) + , m_paintopBox(0) +{ + + KisConfig cfg; + m_font = KGlobalSettings::generalFont(); + m_font.setPointSize((int)cfg.dockerFontSize()); + + m_brushWidget = new KisIconWidget(view, "brushes"); + m_brushWidget->setTextLabel( i18n("Brush Shapes") ); + // XXX: An action without a slot -- that's silly, what kind of action could we use here? + KAction * action = new KWidgetAction(m_brushWidget, + i18n("&Brush"), + 0, + TQT_TQOBJECT(view), + 0, + view->actionCollection(), + "brushes"); + + + m_patternWidget = new KisIconWidget(view, "patterns"); + m_patternWidget->setTextLabel( i18n("Fill Patterns") ); + action = new KWidgetAction(m_patternWidget, + i18n("&Patterns"), + 0, + TQT_TQOBJECT(view), + 0, + view->actionCollection(), + "patterns"); + + m_gradientWidget = new KisIconWidget(view, "gradients"); + m_gradientWidget->setTextLabel( i18n("Gradients") ); + action = new KWidgetAction(m_gradientWidget, + i18n("&Gradients"), + 0, + TQT_TQOBJECT(view), + 0, + view->actionCollection(), + "gradients"); + + m_paintopBox = new KisPaintopBox( view, view, "paintopbox" ); + action = new KWidgetAction(m_paintopBox, + i18n("&Painter's Tools"), + 0, + TQT_TQOBJECT(view), + 0, + view->actionCollection(), + "paintops"); + + m_brushWidget->setFixedSize( 26, 26 ); + m_patternWidget->setFixedSize( 26, 26 ); + m_gradientWidget->setFixedSize( 26, 26 ); + + createBrushesChooser(m_view); + createPatternsChooser(m_view); + createGradientsChooser(m_view); + + m_brushWidget->setPopup(m_brushChooserPopup); + m_brushWidget->setPopupDelay(1); + m_patternWidget->setPopup(m_patternChooserPopup); + m_patternWidget->setPopupDelay(1); + m_gradientWidget->setPopup(m_gradientChooserPopup); + m_gradientWidget->setPopupDelay(1); +} + + +void KisControlFrame::slotSetBrush(KoIconItem *item) +{ + if (item) + m_brushWidget->slotSetItem(*item); +} + +void KisControlFrame::slotSetPattern(KoIconItem *item) +{ + if (item) + m_patternWidget->slotSetItem(*item); +} + +void KisControlFrame::slotSetGradient(KoIconItem *item) +{ + if (item) + m_gradientWidget->slotSetItem(*item); +} + +void KisControlFrame::slotBrushChanged(KisBrush * brush) +{ + KisIconItem *item; + + if((item = m_brushMediator->itemFor(brush))) + { + slotSetBrush(item); + } else { + slotSetBrush( new KisIconItem(brush) ); + } + +} + +void KisControlFrame::slotPatternChanged(KisPattern * pattern) +{ + KisIconItem *item; + if (!pattern) + return; + + if ( (item = m_patternMediator->itemFor(pattern)) ) + slotSetPattern(item); + else + slotSetPattern( new KisIconItem(pattern) ); +} + + +void KisControlFrame::slotGradientChanged(KisGradient * gradient) +{ + KisIconItem *item; + if (!gradient) + return; + + if ( (item = m_gradientMediator->itemFor(gradient)) ) + slotSetGradient(item); + else + slotSetGradient( new KisIconItem(gradient) ); +} + +void KisControlFrame::createBrushesChooser(KisView * view) +{ + + m_brushChooserPopup = new KisPopupFrame(m_brushWidget, "brush_chooser_popup"); + + TQHBoxLayout * l = new TQHBoxLayout(m_brushChooserPopup, 2, 2, "brushpopuptqlayout"); + + TQTabWidget * m_brushesTab = new TQTabWidget(m_brushChooserPopup, "brushestab"); + m_brushesTab->setTabShape(TQTabWidget::Triangular); + m_brushesTab->setFocusPolicy(TQ_NoFocus); + m_brushesTab->setFont(m_font); + m_brushesTab->setMargin(1); + + l->add(m_brushesTab); + + KisAutobrush * m_autobrush = new KisAutobrush(m_brushesTab, "autobrush", i18n("Autobrush")); + m_brushesTab->addTab( m_autobrush, i18n("Autobrush")); + connect(m_autobrush, TQT_SIGNAL(activatedResource(KisResource*)), m_view, TQT_SLOT(brushActivated( KisResource* ))); + + KisBrushChooser * m_brushChooser = new KisBrushChooser(m_brushesTab, "brush_chooser"); + m_brushesTab->addTab( m_brushChooser, i18n("Predefined Brushes")); + + KisCustomBrush* customBrushes = new KisCustomBrush(m_brushesTab, "custombrush", + i18n("Custom Brush"), m_view); + m_brushesTab->addTab( customBrushes, i18n("Custom Brush")); + connect(customBrushes, TQT_SIGNAL(activatedResource(KisResource*)), + m_view, TQT_SLOT(brushActivated(KisResource*))); +#ifdef HAVE_TEXT_BRUSH + KisTextBrush* textBrushes = new KisTextBrush(m_brushesTab, "textbrush", + i18n("Text Brush")/*, m_view*/); + m_brushesTab->addTab( textBrushes, i18n("Text Brush")); + connect(textBrushes, TQT_SIGNAL(activatedResource(KisResource*)), + m_view, TQT_SLOT(brushActivated(KisResource*))); +#endif + + m_brushChooser->setFont(m_font); + m_brushMediator = new KisResourceMediator( m_brushChooser, this); + connect(m_brushMediator, TQT_SIGNAL(activatedResource(KisResource*)), m_view, TQT_SLOT(brushActivated(KisResource*))); + + KisResourceServerBase* rServer; + rServer = KisResourceServerRegistry::instance()->get("ImagePipeBrushServer"); + m_brushMediator->connectServer(rServer); + rServer = KisResourceServerRegistry::instance()->get("BrushServer"); + m_brushMediator->connectServer(rServer); + + KisControlFrame::connect(view, TQT_SIGNAL(brushChanged(KisBrush *)), this, TQT_SLOT(slotBrushChanged( KisBrush *))); + m_brushChooser->setCurrent( 0 ); + m_brushMediator->setActiveItem( m_brushChooser->currentItem() ); + customBrushes->setResourceServer(rServer); + + m_autobrush->activate(); +} + +void KisControlFrame::createPatternsChooser(KisView * view) +{ + m_patternChooserPopup = new KisPopupFrame(m_patternWidget, "pattern_chooser_popup"); + + TQHBoxLayout * l2 = new TQHBoxLayout(m_patternChooserPopup, 2, 2, "patternpopuptqlayout"); + + TQTabWidget * m_patternsTab = new TQTabWidget(m_patternChooserPopup, "patternstab"); + m_patternsTab->setTabShape(TQTabWidget::Triangular); + m_patternsTab->setFocusPolicy(TQ_NoFocus); + m_patternsTab->setFont(m_font); + m_patternsTab->setMargin(1); + l2->add( m_patternsTab ); + + KisPatternChooser * chooser = new KisPatternChooser(m_patternChooserPopup, "pattern_chooser"); + chooser->setFont(m_font); + chooser->setMinimumSize(200, 150); + m_patternsTab->addTab(chooser, i18n("Patterns")); + + KisCustomPattern* customPatterns = new KisCustomPattern(m_patternsTab, "custompatterns", + i18n("Custom Pattern"), m_view); + customPatterns->setFont(m_font); + m_patternsTab->addTab( customPatterns, i18n("Custom Pattern")); + + + m_patternMediator = new KisResourceMediator( chooser, TQT_TQOBJECT(view)); + connect( m_patternMediator, TQT_SIGNAL(activatedResource(KisResource*)), view, TQT_SLOT(patternActivated(KisResource*))); + connect(customPatterns, TQT_SIGNAL(activatedResource(KisResource*)), + TQT_TQOBJECT(view), TQT_SLOT(patternActivated(KisResource*))); + + KisResourceServerBase* rServer; + rServer = KisResourceServerRegistry::instance()->get("PatternServer"); + m_patternMediator->connectServer(rServer); + + KisControlFrame::connect(view, TQT_SIGNAL(patternChanged(KisPattern *)), this, TQT_SLOT(slotPatternChanged( KisPattern *))); + chooser->setCurrent( 0 ); + m_patternMediator->setActiveItem( chooser->currentItem() ); + + customPatterns->setResourceServer(rServer); +} + + +void KisControlFrame::createGradientsChooser(KisView * view) +{ + m_gradientChooserPopup = new KisPopupFrame(m_gradientWidget, "gradient_chooser_popup"); + + TQHBoxLayout * l2 = new TQHBoxLayout(m_gradientChooserPopup, 2, 2, "gradientpopuptqlayout"); + + TQTabWidget * m_gradientTab = new TQTabWidget(m_gradientChooserPopup, "gradientstab"); + m_gradientTab->setTabShape(TQTabWidget::Triangular); + m_gradientTab->setFocusPolicy(TQ_NoFocus); + m_gradientTab->setFont(m_font); + m_gradientTab->setMargin(1); + + l2->add( m_gradientTab); + + KisGradientChooser * m_gradientChooser = new KisGradientChooser(m_view, m_gradientChooserPopup, "gradient_chooser"); + m_gradientChooser->setFont(m_font); + m_gradientChooser->setMinimumSize(200, 150); + m_gradientTab->addTab( m_gradientChooser, i18n("Gradients")); + + m_gradientMediator = new KisResourceMediator( m_gradientChooser, TQT_TQOBJECT(view)); + connect(m_gradientMediator, TQT_SIGNAL(activatedResource(KisResource*)), view, TQT_SLOT(gradientActivated(KisResource*))); + + KisResourceServerBase* rServer; + rServer = KisResourceServerRegistry::instance()->get("GradientServer"); + m_gradientMediator->connectServer(rServer); + + connect(view, TQT_SIGNAL(gradientChanged(KisGradient *)), this, TQT_SLOT(slotGradientChanged( KisGradient *))); + m_gradientChooser->setCurrent( 0 ); + m_gradientMediator->setActiveItem( m_gradientChooser->currentItem() ); +} + + +#include "kis_controlframe.moc" + diff --git a/chalk/ui/kis_controlframe.h b/chalk/ui/kis_controlframe.h new file mode 100644 index 00000000..0c16c77f --- /dev/null +++ b/chalk/ui/kis_controlframe.h @@ -0,0 +1,130 @@ +/* + * kis_controlframe.h - part of Chalk + * + * Copyright (c) 1999 Matthias Elter <elter@kde.org> + * Copyright (c) 2003 Patrick Julien <freak@codepimps.org> + * Copyright (c) 2004 Sven Langkamp <longamp@reallygood.de> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef __kis_controlframe_h__ +#define __kis_controlframe_h__ + +#include <tqpopupmenu.h> + +#include <ktoolbar.h> + +#include <koFrameButton.h> + +class TQWidget; +class TQTabWidget; + +class KToolBar; + +class KoIconItem; +class KisIconWidget; +class KisGradientWidget; + +class KisAutobrush; +class KisAutogradient; +class KisBrush; +class KisBrushChooser; +class KisGradient; +class KisGradientChooser; +class KisItemChooser; +class KisPattern; +class KisResourceMediator; +class KisPaintopBox; +class KisView; + +class KisPopupFrame : public TQPopupMenu { + + Q_OBJECT + TQ_OBJECT + +public: + + KisPopupFrame(TQWidget * tqparent, const char * name = 0); + virtual void keyPressEvent(TQKeyEvent *); + +public: + + void setChooser(KisItemChooser * chooser) { m_chooser = chooser; }; + KisItemChooser * chooser() { return m_chooser; }; + +private: + KisItemChooser * m_chooser; +}; + + +/** + * Control Frame - status display with access to + * color selector, brushes, patterns, and preview + */ +class KisControlFrame : public TQObject //: public KToolBar +{ + Q_OBJECT + TQ_OBJECT + +public: + KisControlFrame(KMainWindow * window, KisView * view, const char *name = 0 ); + virtual ~KisControlFrame() {}; + +public slots: + + void slotSetBrush(KoIconItem *item); + void slotSetPattern(KoIconItem *item); + void slotSetGradient(KoIconItem *item); + + void slotBrushChanged(KisBrush * brush); + void slotPatternChanged(KisPattern * pattern); + void slotGradientChanged(KisGradient * gradient); + +private: + + void createBrushesChooser(KisView * view); + void createPatternsChooser(KisView * view); + void createGradientsChooser(KisView * view); + + +private: + TQFont m_font; + KisView * m_view; + + TQTabWidget * m_brushesTab; + TQTabWidget * m_gradientTab; + + KisIconWidget *m_brushWidget; + KisIconWidget *m_patternWidget; + KisIconWidget *m_gradientWidget; + + KisPopupFrame * m_brushChooserPopup; + KisPopupFrame * m_patternChooserPopup; + KisPopupFrame * m_gradientChooserPopup; + + KisResourceMediator *m_brushMediator; + KisResourceMediator *m_patternMediator; + KisResourceMediator *m_gradientMediator; + + + KisAutobrush * m_autobrush; + KisBrushChooser * m_brushChooser; + KisGradientChooser * m_gradientChooser; + + KisPaintopBox * m_paintopBox; +}; + +#endif + diff --git a/chalk/ui/kis_cursor.cc b/chalk/ui/kis_cursor.cc new file mode 100644 index 00000000..33c6ae04 --- /dev/null +++ b/chalk/ui/kis_cursor.cc @@ -0,0 +1,374 @@ +/* + * kis_cursor.cc - part of KImageShop + * + * Copyright (c) 1999 Matthias Elter <elter@kde.org> + * Copyright (c) 2004 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <tqbitmap.h> +#include <tqcursor.h> +#include <tqimage.h> +#include <tqpainter.h> + +#include <kcursor.h> +#include <kiconloader.h> +#include <kstandarddirs.h> + +#include "kis_cursor.h" +#include "kis_factory.h" + +KisCursor::KisCursor() {} + +/* + * Predefined TQt cursors + */ +TQCursor KisCursor::arrowCursor() +{ + return TQt::arrowCursor; +} + +TQCursor KisCursor::upArrowCursor() +{ + return TQt::upArrowCursor; +} + +TQCursor KisCursor::crossCursor() +{ + return TQt::crossCursor; +} + +TQCursor KisCursor::waitCursor() +{ + return TQt::waitCursor; +} + +TQCursor KisCursor::ibeamCursor() +{ + return TQt::ibeamCursor; +} + +TQCursor KisCursor::sizeVerCursor() +{ + return TQt::sizeVerCursor; +} + +TQCursor KisCursor::sizeHorCursor() +{ + return TQt::sizeHorCursor; +} + +TQCursor KisCursor::sizeBDiagCursor() +{ + return TQt::sizeBDiagCursor; +} + +TQCursor KisCursor::sizeFDiagCursor() +{ + return TQt::sizeFDiagCursor; +} + +TQCursor KisCursor::sizeAllCursor() +{ + return TQt::sizeAllCursor; +} + +TQCursor KisCursor::blankCursor() +{ + return TQt::blankCursor; +} + +TQCursor KisCursor::splitVCursor() +{ + return TQt::splitVCursor; +} + +TQCursor KisCursor::splitHCursor() +{ + return TQt::splitHCursor; +} + +TQCursor KisCursor::pointingHandCursor() +{ + return TQt::pointingHandCursor; +} + + +/* + * Existing custom KimageShop cursors. Use the 'load' function for all new cursors. + */ + +TQCursor KisCursor::pickerCursor() +{ + static unsigned char picker_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x34, 0x00, 0x00, 0x7a, + 0x00, 0x00, 0x7d, 0x00, 0x80, 0x7e, 0x00, 0x60, 0x3f, 0x00, 0xd0, 0x1f, + 0x00, 0xa0, 0x0f, 0x00, 0x50, 0x07, 0x00, 0xc8, 0x06, 0x00, 0xe4, 0x02, + 0x00, 0x72, 0x01, 0x00, 0x39, 0x00, 0x80, 0x1c, 0x00, 0x40, 0x0e, 0x00, + 0x20, 0x07, 0x00, 0x90, 0x03, 0x00, 0xc8, 0x01, 0x00, 0xe4, 0x00, 0x00, + 0x74, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}; + + TQBitmap picker_bitmap(24, 24, picker_bits, true); + TQBitmap picker_tqmask = picker_bitmap.createHeuristicMask( false ); + + return TQCursor( picker_bitmap, picker_tqmask, 1, 22 ); +} + + +TQCursor KisCursor::pickerPlusCursor() +{ + static unsigned char pickerplus_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x34, 0x00, 0x00, 0x7a, + 0x00, 0x00, 0x7d, 0x00, 0x80, 0x7e, 0x00, 0x60, 0x3f, 0x00, 0xd0, 0x1f, + 0x00, 0xa0, 0x0f, 0x00, 0x50, 0x07, 0x00, 0xc8, 0x06, 0x00, 0xe4, 0x02, + 0x00, 0x72, 0x01, 0x00, 0x39, 0x0c, 0x80, 0x1c, 0x0c, 0x40, 0x0e, 0x0c, + 0x20, 0x07, 0x0c, 0x90, 0x83, 0x7f, 0xc8, 0x81, 0x7f, 0xe4, 0x00, 0x0c, + 0x74, 0x00, 0x0c, 0x32, 0x00, 0x0c, 0x0a, 0x00, 0x0c, 0x00, 0x00, 0x00}; + + TQBitmap picker_bitmap(24, 24, pickerplus_bits, true); + TQBitmap picker_tqmask = picker_bitmap.createHeuristicMask( false ); + + return TQCursor( picker_bitmap, picker_tqmask, 1, 22 ); +} + + +TQCursor KisCursor::pickerMinusCursor() +{ + static unsigned char pickerminus_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x34, 0x00, 0x00, 0x7a, + 0x00, 0x00, 0x7d, 0x00, 0x80, 0x7e, 0x00, 0x60, 0x3f, 0x00, 0xd0, 0x1f, + 0x00, 0xa0, 0x0f, 0x00, 0x50, 0x07, 0x00, 0xc8, 0x06, 0x00, 0xe4, 0x02, + 0x00, 0x72, 0x01, 0x00, 0x39, 0x00, 0x80, 0x1c, 0x00, 0x40, 0x0e, 0x00, + 0x20, 0x07, 0x00, 0x90, 0xc3, 0x7f, 0xc8, 0xc1, 0x7f, 0xe4, 0x00, 0x00, + 0x74, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}; + + TQBitmap picker_bitmap(24, 24, pickerminus_bits, true); + TQBitmap picker_tqmask = picker_bitmap.createHeuristicMask( false ); + + return TQCursor( picker_bitmap, picker_tqmask, 1, 22 ); +} + + + +TQCursor KisCursor::penCursor() +{ + static unsigned char pen_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x7d, + 0x00, 0x80, 0x7e, 0x00, 0x40, 0x7f, 0x00, 0xa0, 0x3f, 0x00, 0xd0, 0x1f, + 0x00, 0xe8, 0x0f, 0x00, 0xf4, 0x07, 0x00, 0xfa, 0x03, 0x00, 0xfd, 0x01, + 0x80, 0xfe, 0x00, 0x40, 0x7f, 0x00, 0xa0, 0x3f, 0x00, 0xf0, 0x1f, 0x00, + 0xd0, 0x0f, 0x00, 0x88, 0x07, 0x00, 0x88, 0x03, 0x00, 0xe4, 0x01, 0x00, + 0x7c, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00}; + + TQBitmap pen_bitmap( 24, 24, pen_bits, true ); + TQBitmap pen_tqmask = pen_bitmap.createHeuristicMask( false ); + + return TQCursor( pen_bitmap, pen_tqmask, 1, 22 ); +} + +TQCursor KisCursor::brushCursor() +{ + static unsigned char brush_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x68, 0x00, + 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0xfd, 0x00, + 0x00, 0x80, 0x7e, 0x00, 0x00, 0x40, 0x3f, 0x00, 0x00, 0xa0, 0x1f, 0x00, + 0x00, 0xd0, 0x0f, 0x00, 0x00, 0xe8, 0x07, 0x00, 0x00, 0xf4, 0x03, 0x00, + 0x00, 0xe4, 0x01, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x80, 0x41, 0x00, 0x00, + 0x40, 0x32, 0x00, 0x00, 0xa0, 0x0f, 0x00, 0x00, 0xd0, 0x0f, 0x00, 0x00, + 0xd0, 0x0f, 0x00, 0x00, 0xe8, 0x07, 0x00, 0x00, 0xf4, 0x01, 0x00, 0x00, + 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + TQBitmap brush_bitmap( 25, 23, brush_bits, true ); + TQBitmap brush_tqmask = brush_bitmap.createHeuristicMask( false ); + + return TQCursor( brush_bitmap, brush_tqmask, 1, 21 ); +} + +TQCursor KisCursor::airbrushCursor() +{ + static unsigned char airbrush_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x68, 0x00, 0x00, 0x74, + 0x00, 0x00, 0x7a, 0xf0, 0x00, 0x3d, 0x08, 0x81, 0x1e, 0xe8, 0x41, 0x0f, + 0xe8, 0xa1, 0x07, 0xe8, 0xd1, 0x03, 0xe8, 0xe9, 0x01, 0xe8, 0xf5, 0x00, + 0xe8, 0x7b, 0x00, 0xf0, 0x33, 0x00, 0xf0, 0x23, 0x1f, 0xa0, 0x9f, 0x3f, + 0xd0, 0xff, 0x31, 0xe8, 0xf7, 0x30, 0xf4, 0x03, 0x18, 0xfc, 0x01, 0x0c, + 0xf8, 0x00, 0x06, 0x76, 0x00, 0x03, 0x36, 0x00, 0x03, 0x00, 0x00, 0x00}; + + TQBitmap airbrush_bitmap( 24, 24, airbrush_bits, true ); + TQBitmap airbrush_tqmask = airbrush_bitmap.createHeuristicMask( false ); + + return TQCursor( airbrush_bitmap, airbrush_tqmask, 1, 22 ); +} + +TQCursor KisCursor::eraserCursor() +{ + static unsigned char eraser_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x1d, 0x00, + 0x00, 0x80, 0x3e, 0x00, 0x00, 0x40, 0x7f, 0x00, 0x00, 0xa0, 0xff, 0x00, + 0x00, 0xd0, 0xff, 0x00, 0x00, 0xe8, 0x7f, 0x00, 0x00, 0xf4, 0x3f, 0x00, + 0x00, 0xfe, 0x1f, 0x00, 0x00, 0xf9, 0x0f, 0x00, 0x80, 0xf2, 0x07, 0x00, + 0x40, 0xe7, 0x03, 0x00, 0xa0, 0xcf, 0x01, 0x00, 0xd0, 0x9f, 0x00, 0x00, + 0xe8, 0x7f, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x00, 0xf2, 0x1f, 0x00, 0x00, + 0xe2, 0x0f, 0x00, 0x00, 0xc4, 0x07, 0x00, 0x00, 0x88, 0x03, 0x00, 0x00, + 0x10, 0x01, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + TQBitmap eraser_bitmap( 25, 24, eraser_bits, true ); + TQBitmap eraser_tqmask = eraser_bitmap.createHeuristicMask( false ); + + return TQCursor( eraser_bitmap, eraser_tqmask, 7, 22 ); +} + +TQCursor KisCursor::fillerCursor() +{ + static unsigned char filler_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x28, 0x00, + 0x00, 0x54, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x85, 0x00, 0x80, 0x0a, 0x01, + 0x40, 0x11, 0x01, 0xe0, 0x00, 0x02, 0x58, 0x01, 0x04, 0x2c, 0x02, 0x04, + 0x44, 0x04, 0x08, 0x0c, 0x08, 0x18, 0x3c, 0x00, 0x14, 0x5c, 0x00, 0x0a, + 0x9c, 0x01, 0x05, 0x1c, 0x82, 0x02, 0x18, 0x4c, 0x01, 0x18, 0xb0, 0x00, + 0x08, 0x60, 0x00, 0x00, 0x00, 0x00}; + + TQBitmap filler_bitmap( 22, 22, filler_bits, true ); + TQBitmap filler_tqmask = filler_bitmap.createHeuristicMask( false ); + + return TQCursor( filler_bitmap, filler_tqmask, 3, 20 ); +} + +TQCursor KisCursor::colorChangerCursor() +{ + static unsigned char colorChanger_bits[] = { + 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x10, 0x01, 0x0e, 0x08, 0x02, 0x11, + 0x04, 0x82, 0x20, 0x64, 0x84, 0x20, 0x92, 0x44, 0x46, 0x12, 0x49, 0x5f, + 0x12, 0x31, 0x5f, 0x22, 0x01, 0x5f, 0xc2, 0x00, 0x4e, 0x02, 0x00, 0x40, + 0xc2, 0x00, 0x46, 0xe2, 0x01, 0x4f, 0xe4, 0x19, 0x2f, 0xe4, 0x3d, 0x2f, + 0xe8, 0x3d, 0x17, 0xd0, 0x3c, 0x10, 0x20, 0x38, 0x08, 0x40, 0x00, 0x06, + 0x80, 0x81, 0x01, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00}; + + TQBitmap colorChanger_bitmap( 24, 23, colorChanger_bits, true ); + TQBitmap colorChanger_tqmask = colorChanger_bitmap.createHeuristicMask( false ); + + return TQCursor( colorChanger_bitmap, colorChanger_tqmask, 12, 10 ); +} + +TQCursor KisCursor::zoomCursor() +{ + static unsigned char zoom_bits[] = { + 0x00, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0xf0, 0x3f, 0x00, 0x38, 0x70, 0x00, + 0x8c, 0xcf, 0x00, 0x0c, 0xdf, 0x00, 0x36, 0xbf, 0x01, 0xb6, 0xbf, 0x01, + 0xf6, 0xbf, 0x01, 0xf6, 0xbf, 0x01, 0xe6, 0x9f, 0x00, 0xcc, 0xcf, 0x00, + 0x9c, 0xe7, 0x01, 0x38, 0x70, 0x03, 0xf0, 0xbf, 0x05, 0xc0, 0xef, 0x0b, + 0x00, 0xc0, 0x17, 0x00, 0x80, 0x2f, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x7e, + 0x00, 0x00, 0x7c, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00}; + + TQBitmap zoom_bitmap( 24, 23, zoom_bits, true ); + TQBitmap zoom_tqmask = zoom_bitmap.createHeuristicMask( false ); + + return TQCursor( zoom_bitmap, zoom_tqmask, 9, 8 ); +} + +TQCursor KisCursor::moveCursor() +{ + static unsigned char move_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x7e, 0x00, + 0x00, 0xff, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, + 0x10, 0x18, 0x08, 0x18, 0x18, 0x18, 0x1c, 0x18, 0x38, 0xfe, 0xff, 0x7f, + 0xfe, 0xff, 0x7f, 0x1c, 0x18, 0x38, 0x18, 0x18, 0x18, 0x10, 0x18, 0x08, + 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0xff, 0x00, + 0x00, 0x7e, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00}; + + TQBitmap move_bitmap( 24, 24, move_bits, true ); + TQBitmap move_tqmask = move_bitmap.createHeuristicMask( false ); + + return TQCursor( move_bitmap, move_tqmask, 12, 11 ); +} + +TQCursor KisCursor::handCursor() +{ + return KCursor::handCursor(); +} + +TQCursor KisCursor::selectCursor() +{ + static unsigned char select_bits[] = { + 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0xff, 0xff, 0x7f, + 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00}; + + TQBitmap select_bitmap(23, 23, select_bits, true); + TQBitmap select_tqmask = select_bitmap.createHeuristicMask( false ); + + return TQCursor( select_bitmap, select_tqmask, 11, 11 ); +} + +TQCursor KisCursor::openHandCursor() +{ + return load("openhand_cursor.xpm"); +} + +TQCursor KisCursor::closedHandCursor() +{ + return load("closedhand_cursor.xpm"); +} + +TQCursor KisCursor::rotateCursor() +{ + return load("rotate_cursor.xpm"); +} + +TQCursor KisCursor::load(const TQString & iconName, int hotspotX, int hotspotY) +{ + TQString filename = KisFactory::instance()->dirs()->findResource("kis_pics", iconName); + TQImage cursorImage; + + cursorImage.load(filename); + Q_ASSERT(!cursorImage.isNull()); + Q_ASSERT(cursorImage.hasAlphaBuffer()); + + TQBitmap bitmap(cursorImage.width(), cursorImage.height()); + TQBitmap tqmask(cursorImage.width(), cursorImage.height()); + + TQPainter bitmapPainter(&bitmap); + TQPainter tqmaskPainter(&tqmask); + + for (TQ_INT32 x = 0; x < cursorImage.width(); ++x) { + for (TQ_INT32 y = 0; y < cursorImage.height(); ++y) { + + TQRgb pixel = cursorImage.pixel(x, y); + + if (tqAlpha(pixel) < 128) { + bitmapPainter.setPen(TQt::color0); + tqmaskPainter.setPen(TQt::color0); + } else { + tqmaskPainter.setPen(TQt::color1); + + if (tqGray(pixel) < 128) { + bitmapPainter.setPen(TQt::color1); + } else { + bitmapPainter.setPen(TQt::color0); + } + } + + bitmapPainter.drawPoint(x, y); + tqmaskPainter.drawPoint(x, y); + } + } + + return TQCursor(bitmap, tqmask, hotspotX, hotspotY); +} + diff --git a/chalk/ui/kis_cursor.h b/chalk/ui/kis_cursor.h new file mode 100644 index 00000000..69c5cbd5 --- /dev/null +++ b/chalk/ui/kis_cursor.h @@ -0,0 +1,73 @@ +/* + * kis_cursor.h - part of KImageShop + * + * Copyright (c) 1999 Matthias Elter <elter@kde.org> + * Copyright (c) 2004 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __kis_cursor_h__ +#define __kis_cursor_h__ +#include <koffice_export.h> +class TQCursor; + +class KRITACORE_EXPORT KisCursor +{ + +public: + + KisCursor(); + + // Predefined TQt cursors. + static TQCursor arrowCursor(); // standard arrow cursor + static TQCursor upArrowCursor(); // upwards arrow + static TQCursor crossCursor(); // crosshair + static TQCursor waitCursor(); // hourglass/watch + static TQCursor ibeamCursor(); // ibeam/text entry + static TQCursor sizeVerCursor(); // vertical resize + static TQCursor sizeHorCursor(); // horizontal resize + static TQCursor sizeBDiagCursor(); // diagonal resize (/) + static TQCursor sizeFDiagCursor(); // diagonal resize (\) + static TQCursor sizeAllCursor(); // all directions resize + static TQCursor blankCursor(); // blank/invisible cursor + static TQCursor splitVCursor(); // vertical splitting + static TQCursor splitHCursor(); // horziontal splitting + static TQCursor pointingHandCursor(); // a pointing hand + + // Existing custom KimageShop cursors. Use the 'load' function for all new cursors. + static TQCursor moveCursor(); // move tool cursor + static TQCursor penCursor(); // pen tool cursor + static TQCursor brushCursor(); // brush tool cursor + static TQCursor airbrushCursor(); // airbrush tool cursor + static TQCursor eraserCursor(); // eraser tool cursor + static TQCursor fillerCursor(); // filler tool cursor + static TQCursor pickerCursor(); // color picker cursor + static TQCursor pickerPlusCursor(); // color picker cursor + static TQCursor pickerMinusCursor(); // color picker cursor + static TQCursor colorChangerCursor(); // color changer tool cursor + static TQCursor selectCursor(); // select cursor + static TQCursor zoomCursor(); // zoom tool cursor + static TQCursor handCursor(); // hand tool cursor + static TQCursor openHandCursor(); // Pan tool cursor + static TQCursor closedHandCursor(); // Pan tool cursor + static TQCursor rotateCursor(); // Transform tool cursor + + // Load a cursor from an image file. The image should have an alpha channel + // and will be converted to black and white on loading. Any format loadable by + // TQImage can be used. + static TQCursor load(const TQString & imageFilename, int hotspotX = -1, int hotspotY = -1); +}; +#endif // __kis_cursor_h__ diff --git a/chalk/ui/kis_custom_brush.cc b/chalk/ui/kis_custom_brush.cc new file mode 100644 index 00000000..49a44cc8 --- /dev/null +++ b/chalk/ui/kis_custom_brush.cc @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2005 Bart Coppens <kde@bartcoppens.be> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <KoImageResource.h> +#include <kdebug.h> +#include <tqlabel.h> +#include <tqimage.h> +#include <tqpushbutton.h> +#include <tqcombobox.h> +#include <tqcheckbox.h> +#include <kglobal.h> +#include <kstandarddirs.h> +#include <ktempfile.h> + +#include "kis_view.h" +#include "kis_image.h" +#include "kis_layer.h" +#include "kis_paint_device.h" +#include "kis_brush.h" +#include "kis_imagepipe_brush.h" +#include "kis_custom_brush.h" +#include "kis_resource_mediator.h" +#include "kis_resourceserver.h" +#include "kis_paint_layer.h" +#include "kis_group_layer.h" + +KisCustomBrush::KisCustomBrush(TQWidget *tqparent, const char* name, const TQString& caption, KisView* view) + : KisWdgCustomBrush(tqparent, name), m_view(view) +{ + Q_ASSERT(m_view); + m_mediator = 0; + setCaption(caption); + + m_brush = 0; + + preview->setScaledContents(true); + + connect(addButton, TQT_SIGNAL(pressed()), this, TQT_SLOT(slotAddPredefined())); + connect(brushButton, TQT_SIGNAL(pressed()), this, TQT_SLOT(slotUseBrush())); +// connect(exportButton, TQT_SIGNAL(pressed()), this, TQT_SLOT(slotExport())); + connect(style, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotUpdateCurrentBrush(int))); + connect(colorAsMask, TQT_SIGNAL(stateChanged(int)), this, TQT_SLOT(slotUpdateCurrentBrush(int))); +} + +KisCustomBrush::~KisCustomBrush() { + delete m_brush; +} + +void KisCustomBrush::showEvent(TQShowEvent *) { + slotUpdateCurrentBrush(0); +} + +void KisCustomBrush::slotUpdateCurrentBrush(int) { + delete m_brush; + if (m_view->canvasSubject() && m_view->canvasSubject()->currentImg()) { + createBrush(); + preview->setPixmap(TQPixmap(m_brush->img())); + } else { + m_brush = 0; + } +} + +void KisCustomBrush::slotExport() { + ; +} + +void KisCustomBrush::slotAddPredefined() { + // Save in the directory that is likely to be: ~/.kde/share/apps/chalk/brushes + // a unique file with this brushname + TQString dir = KGlobal::dirs()->saveLocation("data", "chalk/brushes"); + TQString extension; + + if (style->currentItem() == 0) { + extension = ".gbr"; + } else { + extension = ".gih"; + } + KTempFile file(dir, extension); + file.close(); // If we don't, and brush->save first, it might get truncated! + + // Save it to that file + m_brush->setFilename(file.name()); + + // Add it to the brush server, so that it automatically gets to the mediators, and + // so to the other brush choosers can pick it up, if they want to + if (m_server) + m_server->addResource(m_brush->clone()); +} + +void KisCustomBrush::slotUseBrush() { + KisBrush* copy = m_brush->clone(); + + Q_CHECK_PTR(copy); + + emit(activatedResource(copy)); +} + +void KisCustomBrush::createBrush() { + KisImageSP img = m_view->canvasSubject()->currentImg(); + + if (!img) + return; + + if (style->currentItem() == 0) { + m_brush = new KisBrush(img->mergedImage(), 0, 0, img->width(), img->height()); + if (colorAsMask->isChecked()) + m_brush->makeMaskImage(); + return; + } + + // For each layer in the current image, create a new image, and add it to the list + TQValueVector< TQValueVector<KisPaintDevice*> > devices; + devices.push_back(TQValueVector<KisPaintDevice*>()); + int w = img->width(); + int h = img->height(); + + // We only loop over the rootLayer. Since we actually should have a layer selection + // list, no need to elaborate on that here and now + KisLayer* layer = img->rootLayer()->firstChild(); + while (layer) { + KisPaintLayer* paint = 0; + if (layer->visible() && (paint = dynamic_cast<KisPaintLayer*>(layer))) + devices.at(0).push_back(paint->paintDevice()); + layer = layer->nextSibling(); + } + TQValueVector<KisPipeBrushParasite::SelectionMode> modes; + + switch(comboBox2->currentItem()) { + case 0: modes.push_back(KisPipeBrushParasite::Constant); break; + case 1: modes.push_back(KisPipeBrushParasite::Random); break; + case 2: modes.push_back(KisPipeBrushParasite::Incremental); break; + case 3: modes.push_back(KisPipeBrushParasite::Pressure); break; + case 4: modes.push_back(KisPipeBrushParasite::Angular); break; + default: modes.push_back(KisPipeBrushParasite::Incremental); + } + + m_brush = new KisImagePipeBrush(img->name(), w, h, devices, modes); + if (colorAsMask->isChecked()) + m_brush->makeMaskImage(); +} + + +#include "kis_custom_brush.moc" diff --git a/chalk/ui/kis_custom_brush.h b/chalk/ui/kis_custom_brush.h new file mode 100644 index 00000000..56e90553 --- /dev/null +++ b/chalk/ui/kis_custom_brush.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2005 Bart Coppens <kde@bartcoppens.be> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_CUSTOM_BRUSH_H_ +#define KIS_CUSTOM_BRUSH_H_ + +#include <tqobject.h> + +#include "wdgcustombrush.h" + + +class KisResource; +class KisView; +class KisResourceServerBase; + +class KisCustomBrush : public KisWdgCustomBrush +{ + Q_OBJECT + TQ_OBJECT +public: + KisCustomBrush(TQWidget *tqparent, const char* name, const TQString& caption, KisView* view); + virtual ~KisCustomBrush(); + void setResourceServer(KisResourceServerBase* server) { m_server = server; } + +public slots: + void slotUseBrush(); + +signals: + void activatedResource(KisResource *); + +protected: + virtual void showEvent(TQShowEvent *); + +private slots: + void slotExport(); + void slotAddPredefined(); + void slotUpdateCurrentBrush(int); // To connect with activated(int) + +private: + void createBrush(); + KisView* m_view; + KisBrush* m_brush; + KisResourceMediator* m_mediator; + KisResourceServerBase* m_server; +}; + + +#endif // KIS_CUSTOM_BRUSH_H_ diff --git a/chalk/ui/kis_custom_image_widget.cc b/chalk/ui/kis_custom_image_widget.cc new file mode 100644 index 00000000..0b77da9f --- /dev/null +++ b/chalk/ui/kis_custom_image_widget.cc @@ -0,0 +1,110 @@ +/* This file is part of the KOffice project + * Copyright (C) 2005 Thomas Zander <zander@kde.org> + * Copyright (C) 2005 Casper Boemann <cbr@boemann.dk> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; version 2. + + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <kis_custom_image_widget.h> +#include <kis_doc.h> +#include <kis_meta_registry.h> +#include "kis_colorspace_factory_registry.h" +#include "kis_profile.h" +#include "kis_colorspace.h" +#include "kis_id.h" +#include "kis_cmb_idlist.h" +#include "squeezedcombobox.h" +#include "kis_color.h" +#include "kis_image.h" +#include "kis_layer.h" + +#include <kcolorcombo.h> + +#include <kdebug.h> +#include <tqpushbutton.h> +#include <tqslider.h> +#include <tqtextedit.h> +#include <KoUnitWidgets.h> +#include <tqlabel.h> + +KisCustomImageWidget::KisCustomImageWidget(TQWidget *tqparent, KisDoc *doc, TQ_INT32 defWidth, TQ_INT32 defHeight, double resolution, TQString defColorSpaceName, TQString imageName) + : WdgNewImage(tqparent) { + m_doc = doc; + + txtName->setText(imageName); + + intWidth->setValue(defWidth); + intHeight->setValue(defHeight); + doubleResolution->setValue(resolution); + + cmbColorSpaces->setIDList(KisMetaRegistry::instance()->csRegistry()->listKeys()); + cmbColorSpaces->setCurrentText(defColorSpaceName); + + connect(cmbColorSpaces, TQT_SIGNAL(activated(const KisID &)), + this, TQT_SLOT(fillCmbProfiles(const KisID &))); + connect (m_createButton, TQT_SIGNAL( clicked() ), this, TQT_SLOT (buttonClicked()) ); + m_createButton -> setDefault(true); + + fillCmbProfiles(cmbColorSpaces->currentItem()); + lblResolution->hide(); + doubleResolution->hide(); +} + +void KisCustomImageWidget::buttonClicked() { + KisColorSpace * cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(cmbColorSpaces->currentItem(), cmbProfile->currentText()); + + TQColor qc(cmbColor->color()); + + m_doc->newImage(txtName->text(), (TQ_INT32)intWidth->value(), (TQ_INT32)intHeight->value(), cs, KisColor(qc, cs), txtDescription->text(), doubleResolution->value()); + KisImageSP img = m_doc->currentImage(); + if (img) { + KisLayerSP layer = img->activeLayer(); + if (layer) { + layer->setOpacity(backgroundOpacity()); + } + } + emit documentSelected(); +} + +TQ_UINT8 KisCustomImageWidget::backgroundOpacity() const +{ + TQ_INT32 opacity = sliderOpacity->value(); + + if (!opacity) + return 0; + + return (opacity * 255) / 100; +} + +void KisCustomImageWidget::fillCmbProfiles(const KisID & s) +{ + cmbProfile->clear(); + + if (!KisMetaRegistry::instance()->csRegistry()->exists(s)) { + return; + } + + KisColorSpaceFactory * csf = KisMetaRegistry::instance()->csRegistry()->get(s); + if (csf == 0) return; + + TQValueVector<KisProfile *> profileList = KisMetaRegistry::instance()->csRegistry()->profilesFor( csf ); + TQValueVector<KisProfile *> ::iterator it; + for ( it = profileList.begin(); it != profileList.end(); ++it ) { + cmbProfile->insertItem((*it)->productName()); + } + cmbProfile->setCurrentText(csf->defaultProfile()); +} + +#include "kis_custom_image_widget.moc" diff --git a/chalk/ui/kis_custom_image_widget.h b/chalk/ui/kis_custom_image_widget.h new file mode 100644 index 00000000..eef443dc --- /dev/null +++ b/chalk/ui/kis_custom_image_widget.h @@ -0,0 +1,58 @@ +/* This file is part of the KOffice project + * Copyright (C) 2005 Thomas Zander <zander@kde.org> + * Copyright (C) 2005 Casper Boemann <cbr@boemann.dk> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; version 2. + + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#ifndef KIS_CUSTOM_IMAGE_WIDGET_H +#define KIS_CUSTOM_IMAGE_WIDGET_H + +#include <wdgnewimage.h> +#include "kis_global.h" + +class KisDoc; +class KisID; + +/** + * The 'Custom Document' widget in the Chalk startup widget. + * This class embeds the image size and colorspace to allow the user to select the image properties + * for a new empty image document. + */ +class KisCustomImageWidget : public WdgNewImage { + Q_OBJECT + TQ_OBJECT +public: + /** + * Constructor. Please note that this class is being used/created by KisDoc. + * @param tqparent the tqparent widget + * @param doc the document that wants to be altered + */ + KisCustomImageWidget(TQWidget *tqparent, KisDoc *doc, TQ_INT32 defWidth, TQ_INT32 defHeight, double resolution, TQString defColorSpaceName, TQString imageName); + +private slots: + void buttonClicked(); + void fillCmbProfiles(const KisID & s); + +signals: + /// this signal is emitted (as defined by KoDocument) the moment the document is 'ready' + void documentSelected(); + +private: + TQ_UINT8 backgroundOpacity() const; + + KisDoc *m_doc; +}; + +#endif diff --git a/chalk/ui/kis_custom_palette.cc b/chalk/ui/kis_custom_palette.cc new file mode 100644 index 00000000..47bd63b4 --- /dev/null +++ b/chalk/ui/kis_custom_palette.cc @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2005 Bart Coppens <kde@bartcoppens.be> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <KoImageResource.h> +#include <kdebug.h> +#include <tqlineedit.h> +#include <tqimage.h> +#include <tqpushbutton.h> +#include <tqregexp.h> +#include <tqvalidator.h> + +#include <kglobal.h> +#include <kstandarddirs.h> +#include <ktempfile.h> +#include <kcolordialog.h> +#include <kinputdialog.h> +#include <klocale.h> +#include <kmessagebox.h> + +#include "kis_view.h" +#include "kis_palette.h" +#include "kis_palette_view.h" +#include "kis_custom_palette.h" +#include "kis_resource_mediator.h" +#include "kis_resourceserver.h" + +KisCustomPalette::KisCustomPalette(TQWidget *tqparent, const char* name, const TQString& caption, KisView* view) + : KisWdgCustomPalette(tqparent, name), m_view(view) +{ + Q_ASSERT(m_view); + m_mediator = 0; + m_server = 0; + m_editMode = false; + setCaption(caption); + + m_palette = new KisPalette(); + m_ownPalette = true; + this->view->setPalette(m_palette); + + connect(addColor, TQT_SIGNAL(pressed()), this, TQT_SLOT(slotAddNew())); + connect(removeColor, TQT_SIGNAL(pressed()), this, TQT_SLOT(slotRemoveCurrent())); + connect(addPalette, TQT_SIGNAL(pressed()), this, TQT_SLOT(slotAddPredefined())); +} + +KisCustomPalette::~KisCustomPalette() { + if (m_ownPalette) + delete m_palette; +} + +void KisCustomPalette::setPalette(KisPalette* p) { + if (m_ownPalette) + delete m_palette; + m_ownPalette = false; + m_palette = p; + view->setPalette(m_palette); +} + +void KisCustomPalette::setEditMode(bool b) { + m_editMode = b; + + if (m_editMode) { + addPalette->setText(i18n("Save changes")); + } else { + addPalette->setText(i18n("Add to Predefined Palettes")); + } +} + +void KisCustomPalette::slotAddNew() { + // Let the user select a new color + // FIXME also let him add the current paint color to the palette + // or even better, let the color picker have an option 'Add to palette'! + + TQColor color; + int result = KColorDialog::getColor(color); + if (result != KColorDialog::Accepted) + return; + + bool ok; + TQRegExpValidator validator(TQRegExp(".*"), TQT_TQOBJECT(this)); + TQString name = KInputDialog::getText(i18n("Add Color to Palette"), + i18n("Color name (optional):"), + TQString(), &ok, + 0, 0, &validator); + if (!ok) + return; + + KisPaletteEntry entry; + entry.color = color; + entry.name = name; + + m_palette->add(entry); + + // Just reload the palette completely for the view updating + view->setPalette(m_palette); +} + +void KisCustomPalette::slotRemoveCurrent() { + m_palette->remove(view->currentEntry()); + // Just reload the palette completely for the view updating + view->setPalette(m_palette); +} + +void KisCustomPalette::slotAddPredefined() { + m_palette->setName(palettename->text()); + + if (!m_editMode) { + // Save in the directory that is likely to be: ~/.kde/share/apps/chalk/palettes + // a unique file with this palettename + TQString dir = KGlobal::dirs()->saveLocation("data", "chalk/palettes"); + TQString extension; + + extension = ".gpl"; + KTempFile file(dir, extension); + file.close(); // If we don't, and palette->save first, it might get truncated! + + // Save it to that file + m_palette->setFilename(file.name()); + } else { + // The filename is already set + } + + if (!m_palette->save()) { + KMessageBox::error(0, i18n("Cannot write to palette file %1. Maybe it is read-only.") + .tqarg(m_palette->filename()), i18n("Palette")); + return; + } + + // Add it to the palette server, so that it automatically gets to the mediators, and + // so to the other choosers can pick it up, if they want to + // This probably leaks! + if (m_server) + m_server->addResource(new KisPalette(*m_palette)); +} + + +#include "kis_custom_palette.moc" diff --git a/chalk/ui/kis_custom_palette.h b/chalk/ui/kis_custom_palette.h new file mode 100644 index 00000000..7ff9c9d8 --- /dev/null +++ b/chalk/ui/kis_custom_palette.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2005 Bart Coppens <kde@bartcoppens.be> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_CUSTOM_PALETTE_H_ +#define KIS_CUSTOM_PALETTE_H_ + +#include <tqobject.h> + +#include "wdgcustompalette.h" + + +class KisResource; +class KisView; +class KisPalette; +class KisResourceServerBase; + +class KisCustomPalette : public KisWdgCustomPalette +{ + Q_OBJECT + TQ_OBJECT +public: + KisCustomPalette(TQWidget *tqparent, const char* name, const TQString& caption, KisView* view); + virtual ~KisCustomPalette(); + void setResourceServer(KisResourceServerBase* server) { m_server = server; } + void setEditMode(bool b); + bool editMode() const { return m_editMode; } + void setPalette(KisPalette* p); + +signals: + void activatedResource(KisResource *); + +private slots: + void slotAddPredefined(); + void slotAddNew(); + void slotRemoveCurrent(); + +private: + bool m_ownPalette; + bool m_editMode; + KisView* m_view; + KisPalette* m_palette; + KisResourceMediator* m_mediator; + KisResourceServerBase* m_server; +}; + + +#endif // KIS_CUSTOM_PALETTE_H_ diff --git a/chalk/ui/kis_custom_pattern.cc b/chalk/ui/kis_custom_pattern.cc new file mode 100644 index 00000000..64430f1c --- /dev/null +++ b/chalk/ui/kis_custom_pattern.cc @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2006 Bart Coppens <kde@bartcoppens.be> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <KoImageResource.h> +#include <kdebug.h> +#include <tqlabel.h> +#include <tqimage.h> +#include <tqpushbutton.h> +#include <tqcombobox.h> +#include <kglobal.h> +#include <kstandarddirs.h> +#include <ktempfile.h> + +#include "kis_view.h" +#include "kis_image.h" +#include "kis_layer.h" +#include "kis_paint_device.h" +#include "kis_pattern.h" +#include "kis_custom_pattern.h" +#include "kis_resource_mediator.h" +#include "kis_resourceserver.h" +#include "kis_paint_layer.h" + +KisCustomPattern::KisCustomPattern(TQWidget *tqparent, const char* name, const TQString& caption, KisView* view) + : KisWdgCustomPattern(tqparent, name), m_view(view) +{ + Q_ASSERT(m_view); + m_mediator = 0; + setCaption(caption); + + m_pattern = 0; + + preview->setScaledContents(true); + + connect(addButton, TQT_SIGNAL(pressed()), this, TQT_SLOT(slotAddPredefined())); + connect(patternButton, TQT_SIGNAL(pressed()), this, TQT_SLOT(slotUsePattern())); + connect(exportButton, TQT_SIGNAL(pressed()), this, TQT_SLOT(slotExport())); +} + +KisCustomPattern::~KisCustomPattern() { + delete m_pattern; +} + +void KisCustomPattern::showEvent(TQShowEvent *) { + slotUpdateCurrentPattern(0); +} + +void KisCustomPattern::slotUpdateCurrentPattern(int) { + delete m_pattern; + if (m_view->canvasSubject() && m_view->canvasSubject()->currentImg()) { + createPattern(); + preview->setPixmap(TQPixmap(m_pattern->img())); + } else { + m_pattern = 0; + } +} + +void KisCustomPattern::slotExport() { + ; +} + +void KisCustomPattern::slotAddPredefined() { + if (!m_pattern) + return; + + // Save in the directory that is likely to be: ~/.kde/share/apps/chalk/patterns + // a unique file with this pattern name + TQString dir = KGlobal::dirs()->saveLocation("data", "chalk/patterns"); + TQString extension; + + KTempFile file(dir, ".pat"); + file.close(); // If we don't, and pattern->save first, it might get truncated! + + // Save it to that file + m_pattern->setFilename(file.name()); + + // Add it to the pattern server, so that it automatically gets to the mediators, and + // so to the other pattern choosers can pick it up, if they want to + if (m_server) + m_server->addResource(m_pattern->clone()); +} + +void KisCustomPattern::slotUsePattern() { + if (!m_pattern) + return; + KisPattern* copy = m_pattern->clone(); + + Q_CHECK_PTR(copy); + + emit(activatedResource(copy)); +} + +void KisCustomPattern::createPattern() { + KisImageSP img = m_view->canvasSubject()->currentImg(); + + if (!img) + return; + + m_pattern = new KisPattern(img->mergedImage(), 0, 0, img->width(), img->height()); +} + + +#include "kis_custom_pattern.moc" diff --git a/chalk/ui/kis_custom_pattern.h b/chalk/ui/kis_custom_pattern.h new file mode 100644 index 00000000..993c9d10 --- /dev/null +++ b/chalk/ui/kis_custom_pattern.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2006 Bart Coppens <kde@bartcoppens.be> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_CUSTOM_PATTERN_H_ +#define KIS_CUSTOM_PATTERN_H_ + +#include <tqobject.h> + +#include "wdgcustompattern.h" + + +class KisResource; +class KisView; +class KisResourceServerBase; + +class KisCustomPattern : public KisWdgCustomPattern +{ + Q_OBJECT + TQ_OBJECT +public: + KisCustomPattern(TQWidget *tqparent, const char* name, const TQString& caption, KisView* view); + virtual ~KisCustomPattern(); + void setResourceServer(KisResourceServerBase* server) { m_server = server; } + +signals: + void activatedResource(KisResource *); + +protected: + virtual void showEvent(TQShowEvent *); + +private slots: + void slotExport(); + void slotAddPredefined(); + void slotUsePattern(); + void slotUpdateCurrentPattern(int); + +private: + void createPattern(); + KisView* m_view; + KisPattern* m_pattern; + KisResourceMediator* m_mediator; + KisResourceServerBase* m_server; +}; + + +#endif // KIS_CUSTOM_PATTERN_H_ diff --git a/chalk/ui/kis_dlg_adj_layer_props.cc b/chalk/ui/kis_dlg_adj_layer_props.cc new file mode 100644 index 00000000..c955eba3 --- /dev/null +++ b/chalk/ui/kis_dlg_adj_layer_props.cc @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2006 Boudewijn Rempt <boud@valdyas.org> + * Copyright (c) 2007 Benjamin Schleimer <bensch128@yahoo.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include <klocale.h> + +#include <tqgroupbox.h> +#include <tqlabel.h> +#include <tqlayout.h> + +#include <klineedit.h> +#include <klocale.h> + +#include "kis_filter_config_widget.h" +#include "kis_transaction.h" +#include "kis_filter.h" +#include "kis_filter_configuration.h" +#include "kis_filters_listview.h" +#include "kis_image.h" +#include "kis_previewwidget.h" +#include "kis_layer.h" +#include "kis_adjustment_layer.h" +#include "kis_paint_device.h" +#include "kis_paint_layer.h" +#include "kis_group_layer.h" +#include "kis_dlg_adj_layer_props.h" +#include "kis_filter.h" +#include "kis_filter_configuration.h" + +KisDlgAdjLayerProps::KisDlgAdjLayerProps(KisAdjustmentLayerSP layer, + const TQString & layerName, + const TQString & caption, + TQWidget *tqparent, + const char *name) + : KDialogBase(tqparent, name, true, "", Ok | Cancel) +{ + Q_ASSERT( layer ); + m_layer = layer; + + KisLayerSP next = layer->nextSibling(); + Q_ASSERT( next ); + + m_currentConfiguration = layer->filter(); + m_currentFilter = KisFilterRegistry::instance()->get(m_currentConfiguration->name()); + if (!m_currentFilter) { + kdWarning() << "No filter specified!\n"; + } + + KisPaintDeviceSP dev = 0; + + if( next ) + { + KisPaintLayer * pl = dynamic_cast<KisPaintLayer*>(next.data()); + if (pl) { + dev = pl->paintDevice(); + } + else { + KisGroupLayer * gl = dynamic_cast<KisGroupLayer*>(next.data()); + if (gl) { + dev = gl->projection(gl->extent()); + } + else { + KisAdjustmentLayer * al = dynamic_cast<KisAdjustmentLayer*>(next.data()); + if (al) { + dev = al->cachedPaintDevice(); + } + } + } + } else { + dev = new KisPaintDevice(m_layer->image()->colorSpace()); + } + setCaption(caption); + TQWidget * page = new TQWidget(this, "page widget"); + TQHBoxLayout * tqlayout = new TQHBoxLayout(page, 0, 6); + setMainWidget(page); + + m_preview = new KisPreviewWidget(page, "dlgadjustment.preview"); + m_preview->slotSetDevice( dev ); + + connect( m_preview, TQT_SIGNAL(updated()), this, TQT_SLOT(refreshPreview())); + tqlayout->addWidget(m_preview, 1, 1); + + TQVBoxLayout *v1 = new TQVBoxLayout( tqlayout ); + TQHBoxLayout *hl = new TQHBoxLayout( v1 ); + + TQLabel * lblName = new TQLabel(i18n("Layer name:"), page, "lblName"); + hl->addWidget(lblName, 0, 0); + + m_layerName = new KLineEdit(page, "m_layerName"); + m_layerName->setText(layerName); + m_layerName->tqsetSizePolicy(TQSizePolicy::MinimumExpanding, TQSizePolicy::Fixed); + hl->addWidget(m_layerName, 0, 1); + connect( m_layerName, TQT_SIGNAL( textChanged ( const TQString & ) ), this, TQT_SLOT( slotNameChanged( const TQString & ) ) ); + + if ( m_currentFilter ) { + m_currentConfigWidget = m_currentFilter->createConfigurationWidget(page, dev); + if (m_currentConfigWidget) { + m_currentConfigWidget->setConfiguration( m_currentConfiguration ); + } + } + if ( m_currentFilter == 0 || m_currentConfigWidget == 0 ) { + TQLabel * labelNoConfigWidget = new TQLabel( i18n("No configuration options are available for this filter"), page ); + v1->addWidget( labelNoConfigWidget ); + } + else { + v1->addWidget( m_currentConfigWidget ); + connect(m_currentConfigWidget, TQT_SIGNAL(sigPleaseUpdatePreview()), this, TQT_SLOT(slotConfigChanged())); + } + + refreshPreview(); + enableButtonOK( !m_layerName->text().isEmpty() ); +} + +void KisDlgAdjLayerProps::slotNameChanged( const TQString & text ) +{ + enableButtonOK( !text.isEmpty() ); +} + +KisFilterConfiguration * KisDlgAdjLayerProps::filterConfiguration() const +{ + return m_currentFilter->configuration(m_currentConfigWidget); +} + +TQString KisDlgAdjLayerProps::layerName() const +{ + return m_layerName->text(); +} + +void KisDlgAdjLayerProps::slotConfigChanged() +{ + if(m_preview->getAutoUpdate()) + { + refreshPreview(); + } else { + m_preview->needUpdate(); + } +} + +void KisDlgAdjLayerProps::refreshPreview() +{ + if (!m_preview) { + kdDebug() << "no preview!\n"; + return; + } + + if (!m_currentFilter) { + return; + } + KisFilterConfiguration* config = m_currentFilter->configuration(m_currentConfigWidget); + + m_preview->runFilter(m_currentFilter, config); +} + +#include "kis_dlg_adj_layer_props.moc" diff --git a/chalk/ui/kis_dlg_adj_layer_props.h b/chalk/ui/kis_dlg_adj_layer_props.h new file mode 100644 index 00000000..de848002 --- /dev/null +++ b/chalk/ui/kis_dlg_adj_layer_props.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2006 Boudewijn Rempt <boud@valdyas.org> + * Copyright (c) 2007 Benjamin Schleimer <bensch128@yahoo.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_DLG_ADJ_LAYER_PROPS_H +#define KIS_DLG_ADJ_LAYER_PROPS_H + +#include <kdialogbase.h> + +class KisFilter; +class TQIconViewItem; +class TQLabel; +class TQHBoxLayout; +class KisPreviewWidget; +class KisFiltersListView; +class KisFilterConfiguration; +class KisImage; +class TQGroupBox; + +/** + * Create a new adjustment layer. + */ +class KisDlgAdjLayerProps : public KDialogBase +{ + + Q_OBJECT + TQ_OBJECT + +public: + + /** + * Create a new adjustmentlayer dialog + * + * @param img the current image + * @param layername the name of the adjustment layer + * @param caption the caption for the dialog -- create or properties + * @param create if true, set the dialog up for creating a new adj. layer, if false, edit the + * propeties of the current adj. layer + * @param tqparent the widget tqparent of this dialog + * @param name the TQObject name, if any + */ + KisDlgAdjLayerProps(KisAdjustmentLayerSP layer, + const TQString & layerName, + const TQString & caption, + TQWidget *tqparent = 0, + const char *name = 0); + + KisFilterConfiguration * filterConfiguration() const; + TQString layerName() const; + +protected slots: + + void slotNameChanged( const TQString & ); + void slotConfigChanged(); + void refreshPreview(); + +private: + KisImage * m_image; + KisPreviewWidget * m_preview; + KisFilterConfigWidget * m_currentConfigWidget; + KisFilter* m_currentFilter; + KisFilterConfiguration * m_currentConfiguration; + KisAdjustmentLayer * m_layer; + KLineEdit * m_layerName; +}; + +#endif // KIS_DLG_ADJ_LAYER_PROPS_H diff --git a/chalk/ui/kis_dlg_adjustment_layer.cc b/chalk/ui/kis_dlg_adjustment_layer.cc new file mode 100644 index 00000000..22cb9c0d --- /dev/null +++ b/chalk/ui/kis_dlg_adjustment_layer.cc @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2006 Boudewijn Rempt <boud@valdyas.org> + * Copyright (c) 2007 Benjamin Schleimer <bensch128@yahoo.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include <klocale.h> + +#include <tqgroupbox.h> +#include <tqlabel.h> +#include <tqlayout.h> + +#include <klineedit.h> +#include <klocale.h> + +#include "kis_filter_config_widget.h" +#include "kis_transaction.h" +#include "kis_filter.h" +#include "kis_filter_configuration.h" +#include "kis_dlg_adjustment_layer.h" +#include "kis_filters_listview.h" +#include "kis_image.h" +#include "kis_previewwidget.h" +#include "kis_layer.h" +#include "kis_paint_device.h" +#include "kis_paint_layer.h" +#include "kis_group_layer.h" +#include "kis_adjustment_layer.h" +#include "kis_filter.h" +#include "kis_filter_configuration.h" + +KisDlgAdjustmentLayer::KisDlgAdjustmentLayer(KisImage * img, + const TQString & /*layerName*/, + const TQString & caption, + TQWidget *tqparent, + const char *name) + : KDialogBase(tqparent, name, true, "", Ok | Cancel) + , m_image(img) + , m_currentFilter(0) + , m_customName(false) + , m_freezeName(false) +{ + Q_ASSERT(img); + + KisLayerSP activeLayer = img->activeLayer(); + m_dev = 0; + + KisPaintLayer * pl = dynamic_cast<KisPaintLayer*>(activeLayer.data()); + if (pl) { + m_dev = pl->paintDevice(); + } + else { + KisGroupLayer * gl = dynamic_cast<KisGroupLayer*>(activeLayer.data()); + if (gl) { + m_dev = gl->projection(img->bounds()); + } + else { + KisAdjustmentLayer * al = dynamic_cast<KisAdjustmentLayer*>(activeLayer.data()); + if (al) { + m_dev = al->cachedPaintDevice(); + } + } + } + + setCaption(caption); + TQWidget * page = new TQWidget(this, "page widget"); + TQGridLayout * grid = new TQGridLayout(page, 3, 2, 0, 6); + setMainWidget(page); + + TQLabel * lblName = new TQLabel(i18n("Layer name:"), page, "lblName"); + grid->addWidget(lblName, 0, 0); + + m_layerName = new KLineEdit(page, "m_layerName"); + grid->addWidget(m_layerName, 0, 1); + connect( m_layerName, TQT_SIGNAL( textChanged ( const TQString & ) ), this, TQT_SLOT( slotNameChanged( const TQString & ) ) ); + + m_filtersList = new KisFiltersListView(m_dev, page, true, "dlgadjustment.filtersList"); + connect(m_filtersList , TQT_SIGNAL(selectionChanged(TQIconViewItem*)), this, TQT_SLOT(selectionHasChanged(TQIconViewItem* ))); + grid->addMultiCellWidget(m_filtersList, 1, 2, 0, 0); + + m_preview = new KisPreviewWidget(page, "dlgadjustment.preview"); + m_preview->slotSetDevice( m_dev ); + + connect( m_preview, TQT_SIGNAL(updated()), this, TQT_SLOT(refreshPreview())); + grid->addWidget(m_preview, 1, 1); + + m_configWidgetHolder = new TQGroupBox(i18n("Configuration"), page, "currentConfigWidget"); + m_configWidgetHolder->setColumnLayout(0, Qt::Horizontal); + grid->addWidget(m_configWidgetHolder, 2, 1); + + m_labelNoConfigWidget = new TQLabel(i18n("No configuration options are available for this filter"), + m_configWidgetHolder); + m_configWidgetHolder->tqlayout()->add(m_labelNoConfigWidget); + m_labelNoConfigWidget->hide(); + + resize( TQSize(600, 480).expandedTo(tqminimumSizeHint()) ); + + m_currentConfigWidget = 0; + + enableButtonOK(0); +} + +void KisDlgAdjustmentLayer::slotNameChanged( const TQString & text ) +{ + if (m_freezeName) + return; + + m_customName = !text.isEmpty(); + enableButtonOK( m_currentFilter && m_customName ); +} + +KisFilterConfiguration * KisDlgAdjustmentLayer::filterConfiguration() const +{ + return m_currentFilter->configuration(m_currentConfigWidget); +} + +TQString KisDlgAdjustmentLayer::layerName() const +{ + return m_layerName->text(); +} + +void KisDlgAdjustmentLayer::slotConfigChanged() +{ + if(m_preview->getAutoUpdate()) + { + refreshPreview(); + } else { + m_preview->needUpdate(); + } +} + +void KisDlgAdjustmentLayer::refreshPreview() +{ + KisFilterConfiguration* config = m_currentFilter->configuration(m_currentConfigWidget); + + m_preview->runFilter(m_currentFilter, config); +} + +void KisDlgAdjustmentLayer::selectionHasChanged ( TQIconViewItem * item ) +{ + KisFiltersIconViewItem* kisitem = (KisFiltersIconViewItem*) item; + + m_currentFilter = kisitem->filter(); + + if ( m_currentConfigWidget != 0 ) + { + m_configWidgetHolder->tqlayout()->remove(m_currentConfigWidget); + + delete m_currentConfigWidget; + m_currentConfigWidget = 0; + + } else { + + m_labelNoConfigWidget->hide(); + } + + if (m_dev) { + m_currentConfigWidget = m_currentFilter->createConfigurationWidget(m_configWidgetHolder, + m_dev); + } + + if (m_currentConfigWidget != 0) + { + m_configWidgetHolder->tqlayout()->add(m_currentConfigWidget); + m_currentConfigWidget->show(); + connect(m_currentConfigWidget, TQT_SIGNAL(sigPleaseUpdatePreview()), this, TQT_SLOT(slotConfigChanged())); + } else { + m_labelNoConfigWidget->show(); + } + + if (!m_customName) { + m_freezeName = true; + m_layerName->setText(m_currentFilter->id().name()); + m_freezeName = false; + } + + enableButtonOK( !m_layerName->text().isEmpty() ); + refreshPreview(); +} + +#include "kis_dlg_adjustment_layer.moc" diff --git a/chalk/ui/kis_dlg_adjustment_layer.h b/chalk/ui/kis_dlg_adjustment_layer.h new file mode 100644 index 00000000..4e20b8fd --- /dev/null +++ b/chalk/ui/kis_dlg_adjustment_layer.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2006 Boudewijn Rempt <boud@valdyas.org> + * Copyright (c) 2007 Benjamin Schleimer <bensch128@yahoo.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KISDLGAdjustMENTLAYER_H +#define KISDLGAdjustMENTLAYER_H + +#include <kdialogbase.h> + +class KisFilter; +class TQIconViewItem; +class TQLabel; +class TQHBoxLayout; +class KisPreviewWidget; +class KisFiltersListView; +class KisFilterConfiguration; +class KisImage; +class TQGroupBox; + +/** + * Create a new adjustment layer. + */ +class KisDlgAdjustmentLayer : public KDialogBase +{ + + Q_OBJECT + TQ_OBJECT + +public: + + /** + * Create a new adjustmentlayer dialog + * + * @param img the current image + * @param layername the name of the adjustment layer + * @param caption the caption for the dialog -- create or properties + * @param create if true, set the dialog up for creating a new adj. layer, if false, edit the + * propeties of the current adj. layer + * @param tqparent the widget tqparent of this dialog + * @param name the TQObject name, if any + */ + KisDlgAdjustmentLayer(KisImage * img, + const TQString & layerName, + const TQString & caption, + TQWidget *tqparent = 0, + const char *name = 0); + + KisFilterConfiguration * filterConfiguration() const; + TQString layerName() const; + +protected slots: + + void slotNameChanged( const TQString & ); + void slotConfigChanged(); + void refreshPreview(); + void selectionHasChanged ( TQIconViewItem * item ); + +private: + KisImage * m_image; + KisPaintDeviceSP m_dev; + KisFiltersListView * m_filtersList; + KisPreviewWidget * m_preview; + TQGroupBox * m_configWidgetHolder; + TQWidget * m_currentConfigWidget; + KisFilter* m_currentFilter; + KLineEdit * m_layerName; + TQLabel* m_labelNoConfigWidget; + bool m_customName; + bool m_freezeName; +}; + +#endif diff --git a/chalk/ui/kis_dlg_apply_profile.cc b/chalk/ui/kis_dlg_apply_profile.cc new file mode 100644 index 00000000..12134aa0 --- /dev/null +++ b/chalk/ui/kis_dlg_apply_profile.cc @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <tqcombobox.h> +#include <klocale.h> +#include <tqbuttongroup.h> + +#include "kis_factory.h" +#include "kis_colorspace_factory_registry.h" +#include "kis_types.h" +#include "kis_profile.h" +#include "kis_colorspace.h" +#include "kis_dlg_apply_profile.h" +#include "kis_config.h" +#include "kis_id.h" +#include <kis_meta_registry.h> +#include "kis_cmb_idlist.h" +#include "squeezedcombobox.h" +#include "wdgapplyprofile.h" + +// XXX: Hardcode RGBA name. This should be a constant, somewhere. +KisDlgApplyProfile::KisDlgApplyProfile(TQWidget *tqparent, const char *name) + : super(tqparent, name, true, "", Ok | Cancel) +{ + + setCaption(i18n("Apply Image Profile to Clipboard Data")); + m_page = new WdgApplyProfile(this); + + setMainWidget(m_page); + resize(m_page->tqsizeHint()); + + // XXX: This is BAD! (bsar) + fillCmbProfiles(KisID("RGBA", "")); + KisConfig cfg; + m_page->grpRenderIntent->setButton(cfg.renderIntent()); + +} + +KisDlgApplyProfile::~KisDlgApplyProfile() +{ + delete m_page; +} + + +KisProfile * KisDlgApplyProfile::profile() const +{ + TQString profileName; + + profileName = m_page->cmbProfile->currentText(); + + return KisMetaRegistry::instance()->csRegistry()->getProfileByName(profileName); +} + +int KisDlgApplyProfile::renderIntent() const +{ + return m_page->grpRenderIntent->selectedId(); +} + + +// XXX: Copy & paste from kis_custom_image_widget -- refactor to separate class +void KisDlgApplyProfile::fillCmbProfiles(const KisID & s) +{ + m_page->cmbProfile->clear(); + + if (!KisMetaRegistry::instance()->csRegistry()->exists(s)) { + return; + } + + KisColorSpaceFactory * csf = KisMetaRegistry::instance()->csRegistry()->get(s); + if (csf == 0) return; + + TQValueVector<KisProfile *> profileList = KisMetaRegistry::instance()->csRegistry()->profilesFor( csf ); + TQValueVector<KisProfile *> ::iterator it; + for ( it = profileList.begin(); it != profileList.end(); ++it ) { + m_page->cmbProfile->insertItem((*it)->productName()); + } + m_page->cmbProfile->setCurrentText(csf->defaultProfile()); +} + +#include "kis_dlg_apply_profile.moc" + diff --git a/chalk/ui/kis_dlg_apply_profile.h b/chalk/ui/kis_dlg_apply_profile.h new file mode 100644 index 00000000..18f56d0a --- /dev/null +++ b/chalk/ui/kis_dlg_apply_profile.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_DLG_APPLY_PROFILE_H_ +#define KIS_DLG_APPLY_PROFILE_H_ + +#include <kdialogbase.h> + +class KisID; +class WdgApplyProfile; + +class KisDlgApplyProfile : public KDialogBase { + typedef KDialogBase super; + + Q_OBJECT + TQ_OBJECT + +public: + KisDlgApplyProfile(TQWidget *tqparent = 0, + const char *name = 0); + virtual ~KisDlgApplyProfile(); + + + KisProfile * profile() const; + int renderIntent() const; + + void fillCmbProfiles(const KisID & s); + +private: + + WdgApplyProfile * m_page; +}; + +#endif // KIS_DLG_APPLY_PROFILE_H_ + diff --git a/chalk/ui/kis_dlg_image_properties.cc b/chalk/ui/kis_dlg_image_properties.cc new file mode 100644 index 00000000..72c26ec5 --- /dev/null +++ b/chalk/ui/kis_dlg_image_properties.cc @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include <tqbuttongroup.h> +#include <tqpushbutton.h> +#include <tqradiobutton.h> +#include <tqgroupbox.h> +#include <tqlayout.h> +#include <tqlabel.h> +#include <tqspinbox.h> +#include <tqslider.h> +#include <tqtextedit.h> +#include <tqcheckbox.h> + +#include <klocale.h> +#include <kcolorcombo.h> + +#include <KoUnitWidgets.h> + +#include "kis_factory.h" +#include "kis_meta_registry.h" +#include "kis_colorspace_factory_registry.h" +#include "kis_dlg_image_properties.h" +#include "kis_profile.h" +#include "kis_types.h" +#include "kis_image.h" +#include "kis_config.h" +#include "kis_id.h" +#include "kis_cmb_idlist.h" +#include "squeezedcombobox.h" +#include "wdgnewimage.h" + +KisDlgImageProperties::KisDlgImageProperties(KisImageSP image, TQWidget *tqparent, const char *name) + : super(tqparent, name, true, "", Ok | Cancel) +{ + + setCaption(i18n("Image Properties")); + m_page = new WdgNewImage(this); + + m_page->lblResolution->hide(); + m_page->doubleResolution->hide(); + + + m_image = image; + + setMainWidget(m_page); + resize(m_page->tqsizeHint()); + + m_page->txtName->setText(image->name()); + m_page->m_createButton->hide(); + KisConfig cfg; + + m_page->intWidth->setValue(image->width()); + m_page->intHeight->setValue(image->height()); + m_page->txtDescription->setText(image->description()); + m_page->doubleResolution->setValue(image->xRes()); // XXX: separate values for x & y? + + //m_page->cmbColorSpaces->hide(); + //m_page->lblColorSpaces->setText(image->colorSpace()->id().name()); + KisIDList colorSpaces = KisMetaRegistry::instance()->csRegistry()->listKeys(); + KisIDList::iterator i = colorSpaces.tqfind(KisID("WET","")); + if (i != colorSpaces.end()) { + colorSpaces.remove(i); + } + m_page->cmbColorSpaces->setIDList(colorSpaces); + m_page->cmbColorSpaces->setCurrent(image->colorSpace()->id()); + + fillCmbProfiles(image->colorSpace()->id()); + + if (image->getProfile()) { + m_page->cmbProfile->setCurrentText(image->getProfile()->productName()); + } + else { + m_page->cmbProfile->setCurrentItem(0); + } + + m_page->sliderOpacity->setEnabled(false); // XXX re-enable when figured out a way to do this + m_page->opacityPanel->hide(); + m_page->lblOpacity->hide(); + + m_page->cmbColor->setEnabled(false); // XXX re-enable when figured out a way to do this + m_page->cmbColor->hide(); + m_page->lblColor->hide(); + + connect(m_page->cmbColorSpaces, TQT_SIGNAL(activated(const KisID &)), + this, TQT_SLOT(fillCmbProfiles(const KisID &))); + + +} + +KisDlgImageProperties::~KisDlgImageProperties() +{ + delete m_page; +} + +int KisDlgImageProperties::imageWidth() +{ + return m_page->intWidth->value(); +} + +int KisDlgImageProperties::imageHeight() +{ + return m_page->intHeight->value(); +} + +int KisDlgImageProperties::opacity() +{ + return m_page->sliderOpacity->value(); +} + +TQString KisDlgImageProperties::imageName() +{ + return m_page->txtName->text(); +} + +double KisDlgImageProperties::resolution() +{ + return m_page->doubleResolution->value(); +} + +TQString KisDlgImageProperties::description() +{ + return m_page->txtDescription->text(); +} + +KisColorSpace * KisDlgImageProperties::colorSpace() +{ + return KisMetaRegistry::instance()->csRegistry()->getColorSpace(m_page->cmbColorSpaces->currentItem(), m_page->cmbProfile->currentText()); +} + +KisProfile * KisDlgImageProperties::profile() +{ + TQValueVector<KisProfile *> profileList = KisMetaRegistry::instance()->csRegistry()->profilesFor( m_image->colorSpace()->id() ); + TQ_UINT32 index = m_page->cmbProfile->currentItem(); + + if (index < profileList.count()) { + return profileList.at(index); + } else { + return 0; + } +} + +// XXX: Copy & paste from kis_dlg_create_img -- refactor to separate class +void KisDlgImageProperties::fillCmbProfiles(const KisID & s) +{ + + KisColorSpaceFactory * csf = KisMetaRegistry::instance()->csRegistry()->get(s); + m_page->cmbProfile->clear(); + TQValueVector<KisProfile *> profileList = KisMetaRegistry::instance()->csRegistry()->profilesFor( csf ); + TQValueVector<KisProfile *> ::iterator it; + for ( it = profileList.begin(); it != profileList.end(); ++it ) { + m_page->cmbProfile->insertItem((*it)->productName()); + } + + +} + +#include "kis_dlg_image_properties.moc" + diff --git a/chalk/ui/kis_dlg_image_properties.h b/chalk/ui/kis_dlg_image_properties.h new file mode 100644 index 00000000..934adc05 --- /dev/null +++ b/chalk/ui/kis_dlg_image_properties.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_DLG_IMAGE_PROPERTIES_H_ +#define KIS_DLG_IMAGE_PROPERTIES_H_ + +#include <kdialogbase.h> + +#include <kis_types.h> + +class WdgNewImage; +class TQButtonGroup; +class KisID; + +class KisDlgImageProperties : public KDialogBase { + typedef KDialogBase super; + Q_OBJECT + TQ_OBJECT + +public: + KisDlgImageProperties(KisImageSP image, + TQWidget *tqparent = 0, + const char *name = 0); + virtual ~KisDlgImageProperties(); + + int imageWidth(); + int imageHeight(); + int opacity(); + TQString imageName(); + double resolution(); + TQString description(); + KisColorSpace * colorSpace(); + KisProfile * profile(); + +private slots: + + void fillCmbProfiles(const KisID &); + +private: + + WdgNewImage * m_page; + KisImageSP m_image; +}; + + + +#endif // KIS_DLG_IMAGE_PROPERTIES_H_ + diff --git a/chalk/ui/kis_dlg_layer_properties.cc b/chalk/ui/kis_dlg_layer_properties.cc new file mode 100644 index 00000000..68df970b --- /dev/null +++ b/chalk/ui/kis_dlg_layer_properties.cc @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include <limits.h> +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqgroupbox.h> +#include <tqslider.h> +#include <tqstring.h> +#include <klineedit.h> +#include <klocale.h> +#include <kpushbutton.h> +#include <knuminput.h> +#include "kis_global.h" +#include "squeezedcombobox.h" +#include "wdglayerproperties.h" +#include "kis_dlg_layer_properties.h" +#include "kis_cmb_composite.h" +#include "kis_cmb_idlist.h" +#include "kis_profile.h" +#include "kis_int_spinbox.h" +#include "kis_colorspace.h" + +KisDlgLayerProperties::KisDlgLayerProperties(const TQString& deviceName, + TQ_INT32 opacity, + const KisCompositeOp& compositeOp, + const KisColorSpace * colorSpace, + TQWidget *tqparent, const char *name, WFlags f) + : super(tqparent, name, f, name, Ok | Cancel) +{ + m_page = new WdgLayerProperties(this); + m_page->tqlayout()->setMargin(0); + + opacity = int((opacity * 100.0) / 255 + 0.5); + + setCaption(i18n("Layer Properties")); + setMainWidget(m_page); + + m_page->editName->setText(deviceName); + connect( m_page->editName, TQT_SIGNAL( textChanged ( const TQString & ) ), this, TQT_SLOT( slotNameChanged( const TQString & ) ) ); + + m_page->cmbColorSpaces->setCurrent(colorSpace->id()); + m_page->cmbColorSpaces->setEnabled(false); + + TQString profilename; + if (KisProfile* profile = const_cast<KisColorSpace *>(colorSpace)->getProfile()) + profilename = profile->productName(); + m_page->cmbProfile->insertItem(profilename); + m_page->cmbProfile->setEnabled(false); + + m_page->intOpacity->setRange(0, 100, 13); + m_page->intOpacity->setValue(opacity); + + m_page->cmbComposite->setCompositeOpList(colorSpace->userVisiblecompositeOps()); + m_page->cmbComposite->setCurrentItem(compositeOp); + + slotNameChanged( m_page->editName->text() ); +} + +KisDlgLayerProperties::~KisDlgLayerProperties() +{ +} + +void KisDlgLayerProperties::slotNameChanged( const TQString &_text ) +{ + enableButtonOK( !_text.isEmpty() ); +} + +TQString KisDlgLayerProperties::getName() const +{ + return m_page->editName->text(); +} + +int KisDlgLayerProperties::getOpacity() const +{ + TQ_INT32 opacity = m_page->intOpacity->value(); + + if (!opacity) + return 0; + + opacity = int((opacity * 255.0) / 100 + 0.5); + if(opacity>255) + opacity=255; + return opacity; +} + +KisCompositeOp KisDlgLayerProperties::getCompositeOp() const +{ + return m_page->cmbComposite->currentItem(); +} + +#include "kis_dlg_layer_properties.moc" diff --git a/chalk/ui/kis_dlg_layer_properties.h b/chalk/ui/kis_dlg_layer_properties.h new file mode 100644 index 00000000..c2b2a5e0 --- /dev/null +++ b/chalk/ui/kis_dlg_layer_properties.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_DLG_LAYER_PROPERTIES_H_ +#define KIS_DLG_LAYER_PROPERTIES_H_ + +#include <kdialogbase.h> + +class TQWidget; +class WdgLayerProperties; +class KisCompositeOp; +class KisColorSpace; + +class KisDlgLayerProperties : public KDialogBase { + typedef KDialogBase super; + Q_OBJECT + TQ_OBJECT + +public: + KisDlgLayerProperties(const TQString& deviceName, + TQ_INT32 opacity, + const KisCompositeOp& compositeOp, + const KisColorSpace * colorSpace, + TQWidget *tqparent = 0, const char *name = 0, WFlags f = 0); + + virtual ~KisDlgLayerProperties(); + + TQString getName() const; + TQ_INT32 getOpacity() const; + KisCompositeOp getCompositeOp() const; + +protected slots: + void slotNameChanged( const TQString & ); + +private: + WdgLayerProperties * m_page; +}; + +#endif // KIS_DLG_LAYER_PROPERTIES_H_ + diff --git a/chalk/ui/kis_dlg_new_layer.cc b/chalk/ui/kis_dlg_new_layer.cc new file mode 100644 index 00000000..a0a97a7e --- /dev/null +++ b/chalk/ui/kis_dlg_new_layer.cc @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2000 Michael Koch <koch@kde.org> + * Copyright (c) 2000 Patrick Julien <freak@codepimps.org> + * Copyright (c) 2004 Boudewijn Remot <boud@valdyas.org> + * Copyright (c) 2006 Casper Boemann <cbr@boemann.dk> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include <tqgroupbox.h> +#include <tqlabel.h> +#include <tqlayout.h> + +#include <klineedit.h> +#include <klocale.h> +#include <knuminput.h> +#include <kpushbutton.h> + +#include "kis_factory.h" +#include "kis_global.h" +#include "kis_cmb_composite.h" +#include "kis_cmb_idlist.h" +#include "squeezedcombobox.h" +#include "kis_dlg_new_layer.h" +#include <kis_meta_registry.h> +#include "kis_colorspace_factory_registry.h" +#include "kis_profile.h" +#include "kis_colorspace.h" +#include "wdglayerproperties.h" +#include "kis_int_spinbox.h" + +NewLayerDialog::NewLayerDialog(const KisID colorSpaceID, + const TQString & profilename, + const TQString & deviceName, + TQWidget *tqparent, + const char *name) + : super(tqparent, name, true, "", Ok | Cancel) +{ + m_page = new WdgLayerProperties(this); + m_page->tqlayout()->setMargin(0); + + setCaption(i18n("New Layer")); + + setMainWidget(m_page); + + // Name + m_page->editName->setText(deviceName); + + // Opacity + m_page->intOpacity->setRange(0, 100, 13); + m_page->intOpacity->setValue(100); + + // ColorSpace + m_page->cmbColorSpaces->setIDList(KisMetaRegistry::instance()->csRegistry()->listKeys()); + m_page->cmbColorSpaces->setCurrentText(colorSpaceID.id()); + connect(m_page->cmbColorSpaces, TQT_SIGNAL(activated(const KisID &)), + this, TQT_SLOT(fillCmbProfiles(const KisID &))); + connect(m_page->cmbColorSpaces, TQT_SIGNAL(activated(const KisID &)), + this, TQT_SLOT(fillCmbComposite(const KisID &))); + + // Init profiles + fillCmbProfiles(m_page->cmbColorSpaces->currentItem()); + m_page->cmbProfile->setCurrentText(profilename); + + // Init composite op + fillCmbComposite(m_page->cmbColorSpaces->currentItem()); + +/* + connect( m_page->editName, TQT_SIGNAL( textChanged ( const TQString & ) ), this, TQT_SLOT( slotNameChanged( const TQString & ) ) ); + + slotNameChanged( m_page->editName->text() ); +*/ +} + +void NewLayerDialog::setColorSpaceEnabled(bool enabled) +{ + m_page->cmbProfile->setEnabled(enabled); + m_page->cmbColorSpaces->setEnabled(enabled); +} + +void NewLayerDialog::fillCmbProfiles(const KisID & s) +{ + m_page->cmbProfile->clear(); + + if (!KisMetaRegistry::instance()->csRegistry()->exists(s)) { + return; + } + + KisColorSpaceFactory * csf = KisMetaRegistry::instance()->csRegistry()->get(s); + if (csf == 0) return; + + TQValueVector<KisProfile *> profileList = KisMetaRegistry::instance()->csRegistry()->profilesFor( csf ); + TQValueVector<KisProfile *> ::iterator it; + for ( it = profileList.begin(); it != profileList.end(); ++it ) { + m_page->cmbProfile->insertItem((*it)->productName()); + } + m_page->cmbProfile->setCurrentText(csf->defaultProfile()); +} + +void NewLayerDialog::fillCmbComposite(const KisID & s) +{ + m_page->cmbComposite->clear(); + + if (!KisMetaRegistry::instance()->csRegistry()->exists(s)) { + return; + } + + KisColorSpace * cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(s,""); + if (cs) { + m_page->cmbComposite->setCompositeOpList(cs->userVisiblecompositeOps()); + } +} + +int NewLayerDialog::opacity() const +{ + TQ_INT32 opacity = m_page->intOpacity->value(); + + if (!opacity) + return 0; + + opacity = int((opacity * 255.0) / 100 + 0.5); + if(opacity>255) + opacity=255; + return opacity; +} + +KisCompositeOp NewLayerDialog::compositeOp() const +{ + return m_page->cmbComposite->currentItem(); +} + +KisID NewLayerDialog::colorSpaceID() const +{ + return m_page->cmbColorSpaces->currentItem(); +} + +TQString NewLayerDialog::layerName() const +{ + return m_page->editName->text(); +} + +TQString NewLayerDialog::profileName() const +{ + return m_page->cmbProfile-> currentText(); +} + +#include "kis_dlg_new_layer.moc" + diff --git a/chalk/ui/kis_dlg_new_layer.h b/chalk/ui/kis_dlg_new_layer.h new file mode 100644 index 00000000..b484e1dc --- /dev/null +++ b/chalk/ui/kis_dlg_new_layer.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2000 Michael Koch <koch@kde.org> + * Copyright (c) 2000 Patrick Julien <freak@codepimps.org> + * Copyright (c) 2006 Casper Boemann <cbr@boemann.dk> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_DLG_NEW_LAYER_H_ +#define KIS_DLG_NEW_LAYER_H_ + +#include <kdialogbase.h> + +#include "kis_composite_op.h" +#include <kis_global.h> + +class TQWidget; +class KisPaintDevice; +class WdgLayerProperties; + +class NewLayerDialog : public KDialogBase { + typedef KDialogBase super; + Q_OBJECT + TQ_OBJECT + +public: + NewLayerDialog(const KisID colorSpace, + const TQString & profilename, + const TQString & deviceName, + TQWidget *tqparent = 0, + const char *name = 0); + + TQString layerName() const; + KisCompositeOp compositeOp() const; + TQ_INT32 opacity() const; + KisID colorSpaceID() const; + TQString profileName() const; + + void setColorSpaceEnabled(bool enabled); + +private slots: + void fillCmbProfiles(const KisID & s); + void fillCmbComposite(const KisID & s); + +private: + WdgLayerProperties * m_page; +}; + +#endif // KIS_DLG_NEW_LAYER_H_ + diff --git a/chalk/ui/kis_dlg_preferences.cc b/chalk/ui/kis_dlg_preferences.cc new file mode 100644 index 00000000..9f82c0d7 --- /dev/null +++ b/chalk/ui/kis_dlg_preferences.cc @@ -0,0 +1,821 @@ +/* + * preferencesdlg.cc - part of KImageShop + * + * Copyright (c) 1999 Michael Koch <koch@kde.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <tqbitmap.h> +#include <tqbuttongroup.h> +#include <tqcheckbox.h> +#include <tqcursor.h> +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqlineedit.h> +#include <tqpixmap.h> +#include <tqpushbutton.h> +#include <tqslider.h> +#include <tqtoolbutton.h> +#include <tqvbox.h> + +#ifdef HAVE_GL +#include <tqgl.h> +#endif + +#include <KoImageResource.h> + +#include <kcolorbutton.h> +#include <kcombobox.h> +#include <kfiledialog.h> +#include <kiconloader.h> +#include <klineedit.h> +#include <klocale.h> +#include <knuminput.h> +#include <kurlrequester.h> + +#include "squeezedcombobox.h" +#include "kis_cmb_idlist.h" +#include "kis_colorspace.h" +#include "kis_colorspace_factory_registry.h" +#include "kis_cursor.h" +#include "kis_config.h" +#include "kis_dlg_preferences.h" +#include "kis_factory.h" +#include "kis_id.h" +#include "kis_meta_registry.h" +#include "kis_profile.h" + +#include "kis_canvas.h" + +#include "wdgcolorsettings.h" +#include "wdgperformancesettings.h" +#include "wdggeneralsettings.h" + +// for the performance update +#include "tiles/kis_tilemanager.h" + +GeneralTab::GeneralTab( TQWidget *_parent, const char *_name ) + : WdgGeneralSettings( _parent, _name ) +{ + + KisConfig cfg; + + m_cmbtqCursorShape->setCurrentItem(cfg.cursorStyle()); + grpDockability->setButton(cfg.dockability()); + numDockerFontSize->setValue((int)cfg.dockerFontSize()); +} + +void GeneralTab::setDefault() +{ + KisConfig cfg; + + m_cmbtqCursorShape->setCurrentItem( cfg.getDefaultCursorStyle()); + grpDockability->setButton(cfg.getDefaultDockability()); + numDockerFontSize->setValue((int)(cfg.getDefaultDockerFontSize())); +} + +enumCursorStyle GeneralTab::cursorStyle() +{ + return (enumCursorStyle)m_cmbtqCursorShape->currentItem(); +} + +enumKoDockability GeneralTab::dockability() +{ + return (enumKoDockability)grpDockability->selectedId(); +} + +float GeneralTab::dockerFontSize() +{ + return (float)numDockerFontSize->value(); +} + +//--------------------------------------------------------------------------------------------------- + +ColorSettingsTab::ColorSettingsTab(TQWidget *tqparent, const char *name ) + : TQWidget(tqparent, name) +{ + // XXX: Make sure only profiles that fit the specified color model + // are shown in the profile combos + + TQGridLayout * l = new TQGridLayout( this, 1, 1, KDialog::marginHint(), KDialog::spacingHint()); + l->setMargin(0); + m_page = new WdgColorSettings(this); + l->addWidget( m_page, 0, 0); + + KisConfig cfg; + + m_page->cmbWorkingColorSpace->setIDList(KisMetaRegistry::instance()->csRegistry()->listKeys()); + m_page->cmbWorkingColorSpace->setCurrentText(cfg.workingColorSpace()); + + m_page->cmbPrintingColorSpace->setIDList(KisMetaRegistry::instance()->csRegistry()->listKeys()); + m_page->cmbPrintingColorSpace->setCurrentText(cfg.printerColorSpace()); + + refillMonitorProfiles(KisID("RGBA", "")); + refillPrintProfiles(KisID(cfg.printerColorSpace(), "")); + + if(m_page->cmbMonitorProfile->tqcontains(cfg.monitorProfile())) + m_page->cmbMonitorProfile->setCurrentText(cfg.monitorProfile()); + if(m_page->cmbPrintProfile->contains(cfg.printerProfile())) + m_page->cmbPrintProfile->setCurrentText(cfg.printerProfile()); + m_page->chkBlackpoint->setChecked(cfg.useBlackPointCompensation()); + m_page->grpPasteBehaviour->setButton(cfg.pasteBehaviour()); + m_page->cmbMonitorIntent->setCurrentItem(cfg.renderIntent()); + + connect(m_page->cmbPrintingColorSpace, TQT_SIGNAL(activated(const KisID &)), + this, TQT_SLOT(refillPrintProfiles(const KisID &))); +} + +void ColorSettingsTab::setDefault() +{ + m_page->cmbWorkingColorSpace->setCurrentText("RGBA"); + + m_page->cmbPrintingColorSpace->setCurrentText("CMYK"); + refillPrintProfiles(KisID("CMYK", "")); + + m_page->chkBlackpoint->setChecked(false); + m_page->cmbMonitorIntent->setCurrentItem(INTENT_PERCEPTUAL); + m_page->grpPasteBehaviour->setButton(2); +} + + +void ColorSettingsTab::refillMonitorProfiles(const KisID & s) +{ + KisColorSpaceFactory * csf = KisMetaRegistry::instance()->csRegistry()->get(s); + + m_page->cmbMonitorProfile->clear(); + + if ( !csf ) + return; + + TQValueVector<KisProfile *> profileList = KisMetaRegistry::instance()->csRegistry()->profilesFor( csf ); + TQValueVector<KisProfile *> ::iterator it; + for ( it = profileList.begin(); it != profileList.end(); ++it ) { + if ((*it)->deviceClass() == icSigDisplayClass) + m_page->cmbMonitorProfile->insertItem((*it)->productName()); + } + + m_page->cmbMonitorProfile->setCurrentText(csf->defaultProfile()); +} + +void ColorSettingsTab::refillPrintProfiles(const KisID & s) +{ + KisColorSpaceFactory * csf = KisMetaRegistry::instance()->csRegistry()->get(s); + + m_page->cmbPrintProfile->clear(); + + if ( !csf ) + return; + + TQValueVector<KisProfile *> profileList = KisMetaRegistry::instance()->csRegistry()->profilesFor( csf ); + TQValueVector<KisProfile *> ::iterator it; + for ( it = profileList.begin(); it != profileList.end(); ++it ) { + if ((*it)->deviceClass() == icSigOutputClass) + m_page->cmbPrintProfile->insertItem((*it)->productName()); + } + + m_page->cmbPrintProfile->setCurrentText(csf->defaultProfile()); +} + +//--------------------------------------------------------------------------------------------------- + +PerformanceTab::PerformanceTab(TQWidget *tqparent, const char *name ) + : WdgPerformanceSettings(tqparent, name) +{ + // XXX: Make sure only profiles that fit the specified color model + // are shown in the profile combos + + KisConfig cfg; + + // it's scaled from 0 - 6, but the config is in 0 - 300 + m_swappiness->setValue(cfg.swappiness() / 50); + m_maxTiles->setValue(cfg.maxTilesInMem()); +} + +void PerformanceTab::setDefault() +{ + m_swappiness->setValue(3); + m_maxTiles->setValue(500); +} + +//--------------------------------------------------------------------------------------------------- + +TabletSettingsTab::TabletSettingsTab( TQWidget *tqparent, const char *name) + : WdgTabletSettings( tqparent, name ) +{ +#ifdef EXTENDED_X11_TABLET_SUPPORT + initTabletDevices(); +#else + grpTabletDevices->hide(); +#endif +} + +void TabletSettingsTab::setDefault() +{ +} + +void TabletSettingsTab::applySettings() +{ + +#ifdef EXTENDED_X11_TABLET_SUPPORT + applyTabletDeviceSettings(); +#endif +} + +#ifdef EXTENDED_X11_TABLET_SUPPORT +TabletSettingsTab::DeviceSettings::DeviceSettings(KisCanvasWidget::X11TabletDevice *tabletDevice, bool enabled, + TQ_INT32 xAxis, TQ_INT32 yAxis, TQ_INT32 pressureAxis, + TQ_INT32 xTiltAxis, TQ_INT32 yTiltAxis, TQ_INT32 wheelAxis, + TQ_INT32 toolIDAxis, TQ_INT32 serialNumberAxis) + : m_tabletDevice(tabletDevice), + m_enabled(enabled), + m_xAxis(xAxis), + m_yAxis(yAxis), + m_pressureAxis(pressureAxis), + m_xTiltAxis(xTiltAxis), + m_yTiltAxis(yTiltAxis), + m_wheelAxis(wheelAxis), + m_toolIDAxis(toolIDAxis), + m_serialNumberAxis(serialNumberAxis) +{ +} + +TabletSettingsTab::DeviceSettings::DeviceSettings() + : m_tabletDevice(0), + m_enabled(false), + m_xAxis(KisCanvasWidget::X11TabletDevice::NoAxis), + m_yAxis(KisCanvasWidget::X11TabletDevice::NoAxis), + m_pressureAxis(KisCanvasWidget::X11TabletDevice::NoAxis), + m_xTiltAxis(KisCanvasWidget::X11TabletDevice::NoAxis), + m_yTiltAxis(KisCanvasWidget::X11TabletDevice::NoAxis), + m_wheelAxis(KisCanvasWidget::X11TabletDevice::NoAxis), + m_toolIDAxis(KisCanvasWidget::X11TabletDevice::NoAxis), + m_serialNumberAxis(KisCanvasWidget::X11TabletDevice::NoAxis) +{ +} + +void TabletSettingsTab::DeviceSettings::applySettings() +{ + m_tabletDevice->setEnabled(enabled()); + m_tabletDevice->setXAxis(xAxis()); + m_tabletDevice->setYAxis(yAxis()); + m_tabletDevice->setPressureAxis(pressureAxis()); + m_tabletDevice->setXTiltAxis(xTiltAxis()); + m_tabletDevice->setYTiltAxis(yTiltAxis()); + m_tabletDevice->setWheelAxis(wheelAxis()); + m_tabletDevice->setToolIDAxis(toolIDAxis()); + m_tabletDevice->setSerialNumberAxis(serialNumberAxis()); + m_tabletDevice->writeSettingsToConfig(); +} + +void TabletSettingsTab::DeviceSettings::setEnabled(bool enabled) +{ + m_enabled = enabled; +} + +bool TabletSettingsTab::DeviceSettings::enabled() const +{ + return m_enabled; +} + +TQ_INT32 TabletSettingsTab::DeviceSettings::numAxes() const +{ + return m_tabletDevice->numAxes(); +} + +void TabletSettingsTab::DeviceSettings::setXAxis(TQ_INT32 axis) +{ + m_xAxis = axis; +} + +void TabletSettingsTab::DeviceSettings::setYAxis(TQ_INT32 axis) +{ + m_yAxis = axis; +} + +void TabletSettingsTab::DeviceSettings::setPressureAxis(TQ_INT32 axis) +{ + m_pressureAxis = axis; +} + +void TabletSettingsTab::DeviceSettings::setXTiltAxis(TQ_INT32 axis) +{ + m_xTiltAxis = axis; +} + +void TabletSettingsTab::DeviceSettings::setYTiltAxis(TQ_INT32 axis) +{ + m_yTiltAxis = axis; +} + +void TabletSettingsTab::DeviceSettings::setWheelAxis(TQ_INT32 axis) +{ + m_wheelAxis = axis; +} + +void TabletSettingsTab::DeviceSettings::setToolIDAxis(TQ_INT32 axis) +{ + m_toolIDAxis = axis; +} + +void TabletSettingsTab::DeviceSettings::setSerialNumberAxis(TQ_INT32 axis) +{ + m_serialNumberAxis = axis; +} + +TQ_INT32 TabletSettingsTab::DeviceSettings::xAxis() const +{ + return m_xAxis; +} + +TQ_INT32 TabletSettingsTab::DeviceSettings::yAxis() const +{ + return m_yAxis; +} + +TQ_INT32 TabletSettingsTab::DeviceSettings::pressureAxis() const +{ + return m_pressureAxis; +} + +TQ_INT32 TabletSettingsTab::DeviceSettings::xTiltAxis() const +{ + return m_xTiltAxis; +} + +TQ_INT32 TabletSettingsTab::DeviceSettings::yTiltAxis() const +{ + return m_yTiltAxis; +} + +TQ_INT32 TabletSettingsTab::DeviceSettings::wheelAxis() const +{ + return m_wheelAxis; +} + +TQ_INT32 TabletSettingsTab::DeviceSettings::toolIDAxis() const +{ + return m_toolIDAxis; +} + +TQ_INT32 TabletSettingsTab::DeviceSettings::serialNumberAxis() const +{ + return m_serialNumberAxis; +} + +TabletSettingsTab::TabletDeviceSettingsDialog::TabletDeviceSettingsDialog(const TQString& deviceName, DeviceSettings settings, + TQWidget *tqparent, const char *name) + : super(tqparent, name, true, "", Ok | Cancel) +{ + setCaption(i18n("Configure %1").tqarg(deviceName)); + + m_page = new WdgTabletDeviceSettings(this); + + setMainWidget(m_page); + resize(m_page->tqsizeHint()); + + for (TQ_INT32 axis = 0; axis < settings.numAxes(); axis++) { + TQString axisString; + + axisString.setNum(axis); + + m_page->cbX->insertItem(axisString); + m_page->cbY->insertItem(axisString); + m_page->cbPressure->insertItem(axisString); + m_page->cbXTilt->insertItem(axisString); + m_page->cbYTilt->insertItem(axisString); + m_page->cbWheel->insertItem(axisString); +// m_page->cbToolID->insertItem(axisString); +// m_page->cbSerialNumber->insertItem(axisString); + } + + m_page->cbX->insertItem(i18n("None")); + m_page->cbY->insertItem(i18n("None")); + m_page->cbPressure->insertItem(i18n("None")); + m_page->cbXTilt->insertItem(i18n("None")); + m_page->cbYTilt->insertItem(i18n("None")); + m_page->cbWheel->insertItem(i18n("None")); +// m_page->cbToolID->insertItem(i18n("None")); +// m_page->cbSerialNumber->insertItem(i18n("None")); + + if (settings.xAxis() != KisCanvasWidget::X11TabletDevice::NoAxis) { + m_page->cbX->setCurrentItem(settings.xAxis()); + } else { + m_page->cbX->setCurrentItem(settings.numAxes()); + } + + if (settings.yAxis() != KisCanvasWidget::X11TabletDevice::NoAxis) { + m_page->cbY->setCurrentItem(settings.yAxis()); + } else { + m_page->cbY->setCurrentItem(settings.numAxes()); + } + + if (settings.pressureAxis() != KisCanvasWidget::X11TabletDevice::NoAxis) { + m_page->cbPressure->setCurrentItem(settings.pressureAxis()); + } else { + m_page->cbPressure->setCurrentItem(settings.numAxes()); + } + + if (settings.xTiltAxis() != KisCanvasWidget::X11TabletDevice::NoAxis) { + m_page->cbXTilt->setCurrentItem(settings.xTiltAxis()); + } else { + m_page->cbXTilt->setCurrentItem(settings.numAxes()); + } + + if (settings.yTiltAxis() != KisCanvasWidget::X11TabletDevice::NoAxis) { + m_page->cbYTilt->setCurrentItem(settings.yTiltAxis()); + } else { + m_page->cbYTilt->setCurrentItem(settings.numAxes()); + } + + if (settings.wheelAxis() != KisCanvasWidget::X11TabletDevice::NoAxis) { + m_page->cbWheel->setCurrentItem(settings.wheelAxis()); + } else { + m_page->cbWheel->setCurrentItem(settings.numAxes()); + } + +// if (settings.toolIDAxis() != KisCanvasWidget::X11TabletDevice::NoAxis) { +// m_page->cbToolID->setCurrentItem(settings.toolIDAxis()); +// } else { +// m_page->cbToolID->setCurrentItem(settings.numAxes()); +// } +// +// if (settings.serialNumberAxis() != KisCanvasWidget::X11TabletDevice::NoAxis) { +// m_page->cbSerialNumber->setCurrentItem(settings.serialNumberAxis()); +// } else { +// m_page->cbSerialNumber->setCurrentItem(settings.numAxes()); +// } + + m_settings = settings; +} + +TabletSettingsTab::TabletDeviceSettingsDialog::~TabletDeviceSettingsDialog() +{ + delete m_page; +} + +TabletSettingsTab::DeviceSettings TabletSettingsTab::TabletDeviceSettingsDialog::settings() +{ + const TQ_INT32 noAxis = m_settings.numAxes(); + + if (m_page->cbX->currentItem() != noAxis ) { + m_settings.setXAxis(m_page->cbX->currentItem()); + } else { + m_settings.setXAxis(KisCanvasWidget::X11TabletDevice::NoAxis); + } + + if (m_page->cbY->currentItem() != noAxis ) { + m_settings.setYAxis(m_page->cbY->currentItem()); + } else { + m_settings.setYAxis(KisCanvasWidget::X11TabletDevice::NoAxis); + } + + if (m_page->cbPressure->currentItem() != noAxis ) { + m_settings.setPressureAxis(m_page->cbPressure->currentItem()); + } else { + m_settings.setPressureAxis(KisCanvasWidget::X11TabletDevice::NoAxis); + } + + if (m_page->cbXTilt->currentItem() != noAxis ) { + m_settings.setXTiltAxis(m_page->cbXTilt->currentItem()); + } else { + m_settings.setXTiltAxis(KisCanvasWidget::X11TabletDevice::NoAxis); + } + + if (m_page->cbYTilt->currentItem() != noAxis ) { + m_settings.setYTiltAxis(m_page->cbYTilt->currentItem()); + } else { + m_settings.setYTiltAxis(KisCanvasWidget::X11TabletDevice::NoAxis); + } + + if (m_page->cbWheel->currentItem() != noAxis ) { + m_settings.setWheelAxis(m_page->cbWheel->currentItem()); + } else { + m_settings.setWheelAxis(KisCanvasWidget::X11TabletDevice::NoAxis); + } + +// if (m_page->cbToolID->currentItem() != noAxis ) { +// m_settings.setToolIDAxis(m_page->cbToolID->currentItem()); +// } else { +// m_settings.setToolIDAxis(KisCanvasWidget::X11TabletDevice::NoAxis); +// } +// +// if (m_page->cbSerialNumber->currentItem() != noAxis ) { +// m_settings.setSerialNumberAxis(m_page->cbSerialNumber->currentItem()); +// } else { +// m_settings.setSerialNumberAxis(KisCanvasWidget::X11TabletDevice::NoAxis); +// } + + return m_settings; +} + +void TabletSettingsTab::initTabletDevices() +{ + connect(cbTabletDevice, TQT_SIGNAL(activated(int)), TQT_SLOT(slotActivateDevice(int))); + connect(chkEnableTabletDevice, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotSetDeviceEnabled(bool))); + connect(btnConfigureTabletDevice, TQT_SIGNAL(clicked()), TQT_SLOT(slotConfigureDevice())); + + KisCanvasWidget::X11XIDTabletDeviceMap& tabletDevices = KisCanvasWidget::tabletDeviceMap(); + + cbTabletDevice->clear(); + + if (!tabletDevices.empty()) { + KisCanvasWidget::X11XIDTabletDeviceMap::iterator it; + + for (it = tabletDevices.begin(); it != tabletDevices.end(); ++it) { + KisCanvasWidget::X11TabletDevice& device = (*it).second; + + m_deviceSettings.append(DeviceSettings(&device, device.enabled(), device.xAxis(), device.yAxis(), + device.pressureAxis(), device.xTiltAxis(), device.yTiltAxis(), device.wheelAxis(), + device.toolIDAxis(), device.serialNumberAxis())); + cbTabletDevice->insertItem(device.name()); + } + slotActivateDevice(0); + } else { + cbTabletDevice->insertItem(i18n("No devices detected")); + cbTabletDevice->setEnabled(false); + chkEnableTabletDevice->setEnabled(false); + btnConfigureTabletDevice->setEnabled(false); + } +} + +void TabletSettingsTab::slotActivateDevice(int deviceIndex) +{ + bool deviceEnabled = m_deviceSettings[deviceIndex].enabled(); + + chkEnableTabletDevice->setChecked(deviceEnabled); + slotSetDeviceEnabled(deviceEnabled); +} + +void TabletSettingsTab::slotSetDeviceEnabled(bool enabled) +{ + btnConfigureTabletDevice->setEnabled(enabled); + m_deviceSettings[cbTabletDevice->currentItem()].setEnabled(enabled); +} + +void TabletSettingsTab::slotConfigureDevice() +{ + TabletDeviceSettingsDialog dialog(cbTabletDevice->currentText(), m_deviceSettings[cbTabletDevice->currentItem()], + this, "TabletDeviceSettings"); + + if (dialog.exec() == TQDialog::Accepted) + { + m_deviceSettings[cbTabletDevice->currentItem()] = dialog.settings(); + } +} + +void TabletSettingsTab::applyTabletDeviceSettings() +{ + for (TQ_UINT32 deviceIndex = 0; deviceIndex < m_deviceSettings.count(); ++deviceIndex) { + m_deviceSettings[deviceIndex].applySettings(); + } +} + +#else // EXTENDED_X11_TABLET_SUPPORT + +// Fix compilation. tqmoc seems to not see the undefined symbol needed +// for these slots to be declared. +void TabletSettingsTab::slotActivateDevice(int /*deviceIndex*/) +{ +} + +void TabletSettingsTab::slotSetDeviceEnabled(bool /*enabled*/) +{ +} + +void TabletSettingsTab::slotConfigureDevice() +{ +} + +void TabletSettingsTab::applyTabletDeviceSettings() +{ +} + +#endif + +//--------------------------------------------------------------------------------------------------- + +DisplaySettingsTab::DisplaySettingsTab( TQWidget *tqparent, const char *name) + : WdgDisplaySettings( tqparent, name ) +{ +#ifdef HAVE_GL + KisConfig cfg; + + if (!TQGLFormat::hasOpenGL()) { + cbUseOpenGL->setEnabled(false); + //cbUseOpenGLShaders->setEnabled(false); + } else { + cbUseOpenGL->setChecked(cfg.useOpenGL()); + //cbUseOpenGLShaders->setChecked(cfg.useOpenGLShaders()); + //cbUseOpenGLShaders->setEnabled(cfg.useOpenGL()); + } +#else + cbUseOpenGL->setEnabled(false); + //cbUseOpenGLShaders->setEnabled(false); +#endif + + connect(cbUseOpenGL, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotUseOpenGLToggled(bool))); +} + +void DisplaySettingsTab::setDefault() +{ + cbUseOpenGL->setChecked(false); + //cbUseOpenGLShaders->setChecked(false); + //cbUseOpenGLShaders->setEnabled(false); +} + +void DisplaySettingsTab::slotUseOpenGLToggled(bool /*isChecked*/) +{ + //cbUseOpenGLShaders->setEnabled(isChecked); +} + +//--------------------------------------------------------------------------------------------------- +GridSettingsTab::GridSettingsTab(TQWidget* tqparent) : WdgGridSettingsBase(tqparent) +{ + KisConfig cfg; + selectMainStyle->setCurrentItem(cfg.getGridMainStyle()); + selectSubdivisionStyle->setCurrentItem(cfg.getGridSubdivisionStyle()); + +#if KDE_IS_VERSION(3,4,0) + colorMain->setDefaultColor( TQColor( 99, 99, 99 ) ); + colorSubdivision->setDefaultColor( TQColor( 200, 200, 200 ) ); +#endif + colorMain->setColor(cfg.getGridMainColor()); + colorSubdivision->setColor(cfg.getGridSubdivisionColor()); + + intHSpacing->setValue( cfg.getGridHSpacing() ); + intVSpacing->setValue( cfg.getGridVSpacing() ); + intSubdivision->setValue( cfg.getGridSubdivisions()); + intOffsetX->setValue( cfg.getGridOffsetX()); + intOffsetY->setValue( cfg.getGridOffsetY()); + + linkSpacingToggled(true); + connect(bnLinkSpacing, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(linkSpacingToggled( bool ))); + + connect(intHSpacing, TQT_SIGNAL(valueChanged(int)),this,TQT_SLOT(spinBoxHSpacingChanged(int))); + connect(intVSpacing, TQT_SIGNAL(valueChanged(int)),this,TQT_SLOT(spinBoxVSpacingChanged(int))); + + +} + +void GridSettingsTab::setDefault() +{ + KisConfig cfg; + selectMainStyle->setCurrentItem(0); + selectSubdivisionStyle->setCurrentItem(1); + + colorMain->setColor(TQColor(99,99,99)); + colorSubdivision->setColor(TQColor(199,199,199)); + + intHSpacing->setValue( 10 ); + intVSpacing->setValue( 10 ); + intSubdivision->setValue( 1 ); + intOffsetX->setValue( 0 ); + intOffsetY->setValue( 0 ); +} + +void GridSettingsTab::spinBoxHSpacingChanged(int v) +{ + if(m_linkSpacing) + { + intVSpacing->setValue(v); + } +} + +void GridSettingsTab::spinBoxVSpacingChanged(int v ) +{ + if(m_linkSpacing) + { + intHSpacing->setValue(v); + } +} + + +void GridSettingsTab::linkSpacingToggled(bool b) +{ + m_linkSpacing = b; + + KoImageResource kir; + if (b) { + bnLinkSpacing->setPixmap(kir.chain()); + } + else { + bnLinkSpacing->setPixmap(kir.chainBroken()); + } +} + + +//--------------------------------------------------------------------------------------------------- + +PreferencesDialog::PreferencesDialog( TQWidget* tqparent, const char* name ) + : KDialogBase( IconList, i18n("Preferences"), Ok | Cancel | Help | Default /*| Apply*/, Ok, tqparent, name, true, true ) +{ + TQVBox *vbox; + + vbox = addVBoxPage( i18n( "General"), i18n( "General"), BarIcon( "misc", KIcon::SizeMedium )); + m_general = new GeneralTab( vbox ); +#ifdef HAVE_GL + vbox = addVBoxPage ( i18n( "Display" ), i18n( "Display" ), BarIcon( "kscreensaver", KIcon::SizeMedium )); + m_displaySettings = new DisplaySettingsTab( vbox ); +#endif + vbox = addVBoxPage( i18n( "Color Management"), i18n( "Color"), BarIcon( "colorize", KIcon::SizeMedium )); + m_colorSettings = new ColorSettingsTab( vbox ); + + vbox = addVBoxPage( i18n( "Performance"), i18n( "Performance"), BarIcon( "fork", KIcon::SizeMedium )); + m_performanceSettings = new PerformanceTab ( vbox ); + + vbox = addVBoxPage ( i18n( "Tablet" ), i18n( "Tablet" ), BarIcon( "tablet", KIcon::SizeMedium )); + m_tabletSettings = new TabletSettingsTab( vbox ); + + vbox = addVBoxPage ( i18n( "Grid" ), i18n( "Grid" ), BarIcon( "grid", KIcon::SizeMedium )); + m_gridSettings = new GridSettingsTab( vbox ); + +} + +PreferencesDialog::~PreferencesDialog() +{ +} + +void PreferencesDialog::slotDefault() +{ + m_general->setDefault(); + m_colorSettings->setDefault(); + m_tabletSettings->setDefault(); + m_performanceSettings->setDefault(); +#ifdef HAVE_GL + m_displaySettings->setDefault(); +#endif + m_gridSettings->setDefault(); +} + +bool PreferencesDialog::editPreferences() +{ + PreferencesDialog* dialog; + + dialog = new PreferencesDialog(); + bool baccept = ( dialog->exec() == Accepted ); + if( baccept ) + { + KisConfig cfg; + cfg.setCursorStyle(dialog->m_general->cursorStyle()); + cfg.setDockability( dialog->m_general->dockability() ); + cfg.setDockerFontSize( dialog->m_general->dockerFontSize() ); + + // Color settings + cfg.setMonitorProfile( dialog->m_colorSettings->m_page->cmbMonitorProfile->currentText()); + cfg.setWorkingColorSpace( dialog->m_colorSettings->m_page->cmbWorkingColorSpace->currentText()); + cfg.setPrinterColorSpace( dialog->m_colorSettings->m_page->cmbPrintingColorSpace->currentText()); + cfg.setPrinterProfile( dialog->m_colorSettings->m_page->cmbPrintProfile->currentText()); + + cfg.setUseBlackPointCompensation( dialog->m_colorSettings->m_page->chkBlackpoint->isChecked()); + cfg.setPasteBehaviour( dialog->m_colorSettings->m_page->grpPasteBehaviour->selectedId()); + cfg.setRenderIntent( dialog->m_colorSettings->m_page->cmbMonitorIntent->currentItem()); + + // it's scaled from 0 - 6, but the config is in 0 - 300 + cfg.setSwappiness(dialog->m_performanceSettings->m_swappiness->value() * 50); + cfg.setMaxTilesInMem(dialog->m_performanceSettings->m_maxTiles->value()); + // let the tile manager know + KisTileManager::instance()->configChanged(); + + dialog->m_tabletSettings->applySettings(); + +#ifdef HAVE_GL + cfg.setUseOpenGL(dialog->m_displaySettings->cbUseOpenGL->isChecked()); + //cfg.setUseOpenGLShaders(dialog->m_displaySettings->cbUseOpenGLShaders->isChecked()); +#endif + + // Grid settings + cfg.setGridMainStyle( dialog->m_gridSettings->selectMainStyle->currentItem() ); + cfg.setGridSubdivisionStyle( dialog->m_gridSettings->selectSubdivisionStyle->currentItem() ); + + cfg.setGridMainColor( dialog->m_gridSettings->colorMain->color() ); + cfg.setGridSubdivisionColor(dialog->m_gridSettings->colorSubdivision->color() ); + + cfg.setGridHSpacing( dialog->m_gridSettings->intHSpacing->value( )); + cfg.setGridVSpacing( dialog->m_gridSettings->intVSpacing->value( )); + cfg.setGridSubdivisions( dialog->m_gridSettings->intSubdivision->value( )); + cfg.setGridOffsetX( dialog->m_gridSettings->intOffsetX->value( )); + cfg.setGridOffsetY( dialog->m_gridSettings->intOffsetY->value( )); + + } + delete dialog; + return baccept; +} + +#include "kis_dlg_preferences.moc" diff --git a/chalk/ui/kis_dlg_preferences.h b/chalk/ui/kis_dlg_preferences.h new file mode 100644 index 00000000..61f4a586 --- /dev/null +++ b/chalk/ui/kis_dlg_preferences.h @@ -0,0 +1,277 @@ +/* + * preferencesdlg.h - part of KImageShop^WChalk + * + * Copyright (c) 1999 Michael Koch <koch@kde.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __preferencesdlg_h__ +#define __preferencesdlg_h__ + +#include <tqwidget.h> + +#include <kdialogbase.h> + +#include <kopalettemanager.h> + +#include "kis_canvas.h" + +#include "wdggeneralsettings.h" +#include "wdgtabletsettings.h" +#include "wdgtabletdevicesettings.h" +#include "wdgperformancesettings.h" +#include "wdgdisplaysettings.h" +#include "wdggridsettings.h" + +class TQLineEdit; +class TQCheckBox; +class KURLRequester; +class WdgColorSettings; +class KisCmbIDList; +class KisID; + +/** + * "General"-tab for preferences dialog + */ +class GeneralTab : public WdgGeneralSettings +{ + Q_OBJECT + TQ_OBJECT + +public: + + GeneralTab( TQWidget *tqparent = 0, const char *name = 0 ); + + enumCursorStyle cursorStyle(); + enumKoDockability dockability(); + float dockerFontSize(); + + void setDefault(); + +}; + +//======================= + +class ColorSettingsTab : public TQWidget +{ + Q_OBJECT + TQ_OBJECT + +public: + + ColorSettingsTab( TQWidget *tqparent = 0, const char * name = 0 ); + +private slots: + + void refillMonitorProfiles(const KisID & s); + void refillPrintProfiles(const KisID & s); + +public: + void setDefault(); + WdgColorSettings * m_page; +}; + + +/** + * "Performance"-tab for preferences dialog + */ +class PerformanceTab : public WdgPerformanceSettings +{ +Q_OBJECT + TQ_OBJECT + +public: + PerformanceTab( TQWidget *tqparent = 0, const char *name = 0 ); + +public: + void setDefault(); +}; + +//======================= + + +/** + * Tablet settings tab for preferences dialog + */ +class TabletSettingsTab : public WdgTabletSettings +{ +Q_OBJECT + TQ_OBJECT + +public: + TabletSettingsTab( TQWidget *tqparent = 0, const char *name = 0 ); + +public: + void setDefault(); + void applySettings(); + +private slots: + void slotActivateDevice(int deviceIndex); + void slotSetDeviceEnabled(bool enabled); + void slotConfigureDevice(); + void applyTabletDeviceSettings(); + +#ifdef EXTENDED_X11_TABLET_SUPPORT + +private: + class DeviceSettings { + public: + DeviceSettings(KisCanvasWidget::X11TabletDevice *tabletDevice, bool enabled, + TQ_INT32 xAxis, TQ_INT32 yAxis, TQ_INT32 pressureAxis, + TQ_INT32 xTiltAxis, TQ_INT32 yTiltAxis, TQ_INT32 wheelAxis, + TQ_INT32 toolIDAxis, TQ_INT32 serialNumberAxis); + DeviceSettings(); + + void applySettings(); + + void setEnabled(bool enabled); + bool enabled() const; + + TQ_INT32 numAxes() const; + + void setXAxis(TQ_INT32 axis); + void setYAxis(TQ_INT32 axis); + void setPressureAxis(TQ_INT32 axis); + void setXTiltAxis(TQ_INT32 axis); + void setYTiltAxis(TQ_INT32 axis); + void setWheelAxis(TQ_INT32 axis); + void setToolIDAxis(TQ_INT32 axis); + void setSerialNumberAxis(TQ_INT32 axis); + + TQ_INT32 xAxis() const; + TQ_INT32 yAxis() const; + TQ_INT32 pressureAxis() const; + TQ_INT32 xTiltAxis() const; + TQ_INT32 yTiltAxis() const; + TQ_INT32 wheelAxis() const; + TQ_INT32 toolIDAxis() const; + TQ_INT32 serialNumberAxis() const; + + private: + KisCanvasWidget::X11TabletDevice *m_tabletDevice; + + bool m_enabled; + TQ_INT32 m_xAxis; + TQ_INT32 m_yAxis; + TQ_INT32 m_pressureAxis; + TQ_INT32 m_xTiltAxis; + TQ_INT32 m_yTiltAxis; + TQ_INT32 m_wheelAxis; + TQ_INT32 m_toolIDAxis; + TQ_INT32 m_serialNumberAxis; + }; + + class TabletDeviceSettingsDialog : public KDialogBase { + typedef KDialogBase super; + + public: + TabletDeviceSettingsDialog(const TQString& deviceName, + DeviceSettings settings, + TQWidget *tqparent = 0, + const char *name = 0); + virtual ~TabletDeviceSettingsDialog(); + + DeviceSettings settings(); + + private: + WdgTabletDeviceSettings *m_page; + DeviceSettings m_settings; + }; + + void initTabletDevices(); + + TQValueVector<DeviceSettings> m_deviceSettings; +#endif +}; + +//======================= + + +/** + * Display settings tab for preferences dialog + */ +class DisplaySettingsTab : public WdgDisplaySettings +{ +Q_OBJECT + TQ_OBJECT + +public: + DisplaySettingsTab( TQWidget *tqparent = 0, const char *name = 0 ); + +public: + void setDefault(); +protected slots: + void slotUseOpenGLToggled(bool isChecked); +}; + +//======================= + + +/** + * Grid settings tab for preferences dialog + */ +class GridSettingsTab : public WdgGridSettingsBase { + Q_OBJECT + TQ_OBJECT + public: + GridSettingsTab(TQWidget* tqparent); + public: + void setDefault(); + private slots: + void linkSpacingToggled(bool); + void spinBoxHSpacingChanged(int ); + void spinBoxVSpacingChanged(int ); + private: + bool m_linkSpacing; +}; + +//======================= + + +/** + * Preferences dialog of KImageShop^WKrayon^WChalk + */ +class PreferencesDialog : public KDialogBase +{ + Q_OBJECT + TQ_OBJECT + +public: + + static bool editPreferences(); + + +protected: + + PreferencesDialog( TQWidget *tqparent = 0, const char *name = 0 ); + ~PreferencesDialog(); + +protected: + + GeneralTab* m_general; + ColorSettingsTab* m_colorSettings; + PerformanceTab* m_performanceSettings; + TabletSettingsTab * m_tabletSettings; + DisplaySettingsTab * m_displaySettings; + GridSettingsTab* m_gridSettings; + +protected slots: + + void slotDefault(); + +}; + +#endif diff --git a/chalk/ui/kis_doc.cc b/chalk/ui/kis_doc.cc new file mode 100644 index 00000000..e60e6524 --- /dev/null +++ b/chalk/ui/kis_doc.cc @@ -0,0 +1,1171 @@ +/* + * Copyright (c) 1999 Matthias Elter <me@kde.org> + * Copyright (c) 2000 John Califf <jcaliff@compuzone.net> + * Copyright (c) 2001 Toshitaka Fujioka <fujioka@kde.org> + * Copyright (c) 2002, 2003 Patrick Julien <freak@codepimps.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +// TQt +#include <tqapplication.h> +#include <tqdom.h> +#include <tqimage.h> +#include <tqpainter.h> +#include <tqtl.h> +#include <tqstringlist.h> +#include <tqwidget.h> +#include <tqpaintdevicemetrics.h> + +// KDE +#include <dcopobject.h> +#include <kapplication.h> +#include <kcommand.h> +#include <kdebug.h> +#include <kimageio.h> +#include <kfiledialog.h> +#include <kglobal.h> +#include <kmimetype.h> +#include <knotifyclient.h> +#include <klocale.h> +#include <kmessagebox.h> + +// KOffice +#include <KoFilterManager.h> +#include <KoMainWindow.h> +#include <KoQueryTrader.h> +#include <KoStore.h> +#include <KoStoreDevice.h> +#include <KoTemplateChooseDia.h> +#include <KoApplication.h> +#include <KoCommandHistory.h> + +// Local +#include <kis_clipboard.h> +#include <kis_meta_registry.h> +#include "kis_annotation.h" +#include "kis_types.h" +#include "kis_config.h" +#include "kis_debug_areas.h" +#include "kis_doc.h" +#include "kis_factory.h" +#include "kis_image.h" +#include "kis_layer.h" +#include "kis_paint_layer.h" +#include "kis_nameserver.h" +#include "kis_painter.h" +#include "kis_selection.h" +#include "kis_fill_painter.h" +#include "kis_command.h" +#include "kis_view.h" +#include "kis_colorspace.h" +#include "kis_colorspace_factory_registry.h" +#include "kis_profile.h" +#include "kis_id.h" +#include "kis_part_layer.h" +#include "kis_doc_iface.h" +#include "kis_paint_device_action.h" +#include "kis_custom_image_widget.h" +#include "kis_load_visitor.h" +#include "kis_save_visitor.h" +#include "kis_savexml_visitor.h" + +static const char *CURRENT_DTD_VERSION = "1.3"; + +/** + * Mime type for this app - not same as file type, but file types + * can be associated with a mime type and are opened with applications + * associated with the same mime type + */ +#define APP_MIMETYPE "application/x-chalk" + +/** + * Mime type for native file format + */ +#define NATIVE_MIMETYPE "application/x-kra" + +namespace { + class KisCommandImageMv : public KisCommand { + typedef KisCommand super; + + public: + KisCommandImageMv(KisDoc *doc, + KisUndoAdapter *adapter, + const TQString& name, + const TQString& oldName) : super(i18n("Rename Image"), adapter) + { + m_doc = doc; + m_name = name; + m_oldName = oldName; + } + + virtual ~KisCommandImageMv() + { + } + + virtual void execute() + { + adapter()->setUndo(false); + m_doc->renameImage(m_oldName, m_name); + adapter()->setUndo(true); + } + + virtual void unexecute() + { + adapter()->setUndo(false); + m_doc->renameImage(m_name, m_oldName); + adapter()->setUndo(true); + } + + private: + KisDoc *m_doc; + TQString m_name; + TQString m_oldName; + }; + +} + +KisDoc::KisDoc(TQWidget *tqparentWidget, const char *widgetName, TQObject *tqparent, const char *name, bool singleViewMode) : + super(tqparentWidget, widgetName, tqparent, name, singleViewMode) +{ + + m_undo = false; + m_dcop = 0; + m_cmdHistory = 0; + m_nserver = 0; + m_currentImage = 0; + m_currentMacro = 0; + m_macroNestDepth = 0; + m_ioProgressBase = 0; + m_ioProgressTotalSteps = 0; + + setInstance( KisFactory::instance(), false ); + setTemplateType( "chalk_template" ); + + init(); + + if (name) + dcopObject(); +} + +KisDoc::~KisDoc() +{ + delete m_cmdHistory; + delete m_nserver; + m_undoListeners.setAutoDelete(false); + delete m_dcop; +} + +TQCString KisDoc::mimeType() const +{ + return APP_MIMETYPE; +} + +DCOPObject *KisDoc::dcopObject() +{ + if (!m_dcop) { + m_dcop = new KisDocIface(this); + Q_CHECK_PTR(m_dcop); + } + return m_dcop; +} + +bool KisDoc::initDoc(InitDocFlags flags, TQWidget* tqparentWidget) +{ + if (!init()) + return false; + + bool ok = false; + + TQString file; + KoTemplateChooseDia::DialogType dlgtype; + + if (flags != KoDocument::InitDocFileNew) { + dlgtype = KoTemplateChooseDia::Everything; + } else { + dlgtype = KoTemplateChooseDia::OnlyTemplates; + } + + KoTemplateChooseDia::ReturnType ret = + KoTemplateChooseDia::choose(KisFactory::instance(), + file, + dlgtype, + "chalk_template", + tqparentWidget); + setUndo(false); + + if (ret == KoTemplateChooseDia::Template) { + resetURL(); + ok = loadNativeFormat( file ); + setEmpty(); + ok = true; + + } else if (ret == KoTemplateChooseDia::File) { + KURL url( file ); + ok = openURL(url); + } else if (ret == KoTemplateChooseDia::Empty) { + setEmpty(); + ok = true; + } + + setModified(false); + KisConfig cfg; + setUndo(cfg.undoEnabled()); + + return ok; +} + +void KisDoc::openExistingFile(const TQString& file) +{ + setUndo(false); + + KoDocument::openExistingFile(file); + + setUndo(true); +} + +void KisDoc::openTemplate(const TQString& file) +{ + setUndo(false); + + KoDocument::openTemplate(file); + + setUndo(true); +} + +bool KisDoc::init() +{ + if (m_cmdHistory) { + delete m_cmdHistory; + m_cmdHistory = 0; + } + + if (m_nserver) { + delete m_nserver; + m_nserver = 0; + } + + m_cmdHistory = new KoCommandHistory(actionCollection(), true); + Q_CHECK_PTR(m_cmdHistory); + + connect(m_cmdHistory, TQT_SIGNAL(documentRestored()), this, TQT_SLOT(slotDocumentRestored())); + connect(m_cmdHistory, TQT_SIGNAL(commandExecuted(KCommand *)), this, TQT_SLOT(slotCommandExecuted(KCommand *))); + setUndo(true); + + m_nserver = new KisNameServer(i18n("Image %1"), 1); + Q_CHECK_PTR(m_nserver); + + if (!KisMetaRegistry::instance()->csRegistry()->exists(KisID("RGBA",""))) { + KMessageBox::sorry(0, i18n("No colorspace modules loaded: cannot run Chalk")); + return false; + } + + m_undoListeners.setAutoDelete(false); + + return true; +} + +TQDomDocument KisDoc::saveXML() +{ + TQDomDocument doc = createDomDocument("DOC", CURRENT_DTD_VERSION); + TQDomElement root = doc.documentElement(); + + root.setAttribute("editor", "Chalk"); + root.setAttribute("depth", sizeof(TQ_UINT8)); + root.setAttribute("syntaxVersion", "1"); + + root.appendChild(saveImage(doc, m_currentImage)); + + return doc; +} + +bool KisDoc::loadOasis( const TQDomDocument&, KoOasisStyles&, const TQDomDocument&, KoStore* ) +{ + //XXX: todo (and that includes defining an OASIS format for layered 2D raster data!) + return false; +} + + +bool KisDoc::saveOasis( KoStore*, KoXmlWriter* ) +{ + //XXX: todo (and that includes defining an OASIS format for layered 2D raster data!) + return false; +} + +bool KisDoc::loadXML(TQIODevice *, const TQDomDocument& doc) +{ + TQDomElement root; + TQString attr; + TQDomNode node; + KisImageSP img; + + if (!init()) + return false; + if (doc.doctype().name() != "DOC") + return false; + root = doc.documentElement(); + attr = root.attribute("syntaxVersion"); + if (attr.toInt() > 1) + return false; + if ((attr = root.attribute("depth")).isNull()) + return false; + m_conversionDepth = attr.toInt(); + + if (!root.hasChildNodes()) { + return false; // XXX used to be: return slotNewImage(); + } + + setUndo(false); + + for (node = root.firstChild(); !node.isNull(); node = node.nextSibling()) { + if (node.isElement()) { + if (node.nodeName() == "IMAGE") { + TQDomElement elem = node.toElement(); + if (!(img = loadImage(elem))) + return false; + m_currentImage = img; + } else { + return false; + } + } + } + + emit loadingFinished(); + return true; +} + +bool KisDoc::loadChildren(KoStore* store) { + TQPtrListIterator<KoDocumentChild> it(tqchildren()); + for( ; it.current(); ++it ) { + if (!it.current()->loadDocument(store)) { + return false; + } + } + return true; +} + +TQDomElement KisDoc::saveImage(TQDomDocument& doc, KisImageSP img) +{ + TQDomElement image = doc.createElement("IMAGE"); + + Q_ASSERT(img); + image.setAttribute("name", img->name()); + image.setAttribute("mime", "application/x-kra"); + image.setAttribute("width", img->width()); + image.setAttribute("height", img->height()); + image.setAttribute("colorspacename", img->colorSpace()->id().id()); + image.setAttribute("description", img->description()); + // XXX: Save profile as blob inside the image, instead of the product name. + if (img->getProfile() && img->getProfile()-> valid()) + image.setAttribute("profile", img->getProfile()->productName()); + image.setAttribute("x-res", img->xRes()); + image.setAttribute("y-res", img->yRes()); + + TQ_UINT32 count=0; + KisSaveXmlVisitor visitor(doc, image, count, true); + + m_currentImage->rootLayer()->accept(visitor); + + return image; +} + +KisImageSP KisDoc::loadImage(const TQDomElement& element) +{ + + KisConfig cfg; + TQString attr; + TQDomNode node; + TQDomNode child; + KisImageSP img; + TQString name; + TQ_INT32 width; + TQ_INT32 height; + TQString description; + TQString profileProductName; + double xres; + double yres; + TQString colorspacename; + KisColorSpace * cs; + + if ((attr = element.attribute("mime")) == NATIVE_MIMETYPE) { + if ((name = element.attribute("name")).isNull()) + return 0; + if ((attr = element.attribute("width")).isNull()) + return 0; + width = attr.toInt(); + if ((attr = element.attribute("height")).isNull()) + return 0; + height = attr.toInt(); + + description = element.attribute("description"); + + if ((attr = element.attribute("x-res")).isNull()) + xres = 100.0; + xres = attr.toDouble(); + + if ((attr = element.attribute("y-res")).isNull()) + yres = 100.0; + yres = attr.toDouble(); + + if ((colorspacename = element.attribute("colorspacename")).isNull()) + { + // An old file: take a reasonable default. + // Chalk didn't support anything else in those + // days anyway. + colorspacename = "RGBA"; + } + + // A hack for an old colorspacename + if (colorspacename == "Grayscale + Alpha") + colorspacename = "GRAYA"; + + if ((profileProductName = element.attribute("profile")).isNull()) { + // no mention of profile so get default profile + cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(colorspacename,""); + } + else { + cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(colorspacename, profileProductName); + } + + if (cs == 0) { + kdWarning(DBG_AREA_FILE) << "Could not open colorspace\n"; + return 0; + } + + img = new KisImage(this, width, height, cs, name); + img->blockSignals(true); // Don't send out signals while we're building the image + Q_CHECK_PTR(img); + connect( img, TQT_SIGNAL( sigImageModified() ), this, TQT_SLOT( slotImageUpdated() )); + img->setDescription(description); + img->setResolution(xres, yres); + + loadLayers(element, img, img->rootLayer().data()); + + } + + img->notifyImageLoaded(); + + return img; +} + +void KisDoc::loadLayers(const TQDomElement& element, KisImageSP img, KisGroupLayerSP tqparent) +{ + TQDomNode node = element.firstChild(); + TQDomNode child; + + if(!node.isNull()) + { + if (node.isElement()) { + if (node.nodeName() == "LAYERS") { + for (child = node.firstChild(); !child.isNull(); child = child.nextSibling()) { + KisLayerSP layer = loadLayer(child.toElement(), img); + + if (!layer) { + kdWarning(DBG_AREA_FILE) << "Could not load layer\n"; + } + else { + img->nextLayerName(); // Make sure the nameserver is current with the number of layers. + img->addLayer(layer, tqparent, 0); + } + } + } + } + } +} + +KisLayerSP KisDoc::loadLayer(const TQDomElement& element, KisImageSP img) +{ + // Nota bene: If you add new properties to layers, you should + // ALWAYS define a default value in case the property is not + // present in the layer definition: this helps a LOT with backward + // compatibilty. + TQString attr; + TQString name; + TQ_INT32 x; + TQ_INT32 y; + TQ_INT32 opacity; + bool visible; + bool locked; + + if ((name = element.attribute("name")).isNull()) + return 0; + + if ((attr = element.attribute("x")).isNull()) + return 0; + x = attr.toInt(); + + if ((attr = element.attribute("y")).isNull()) + return 0; + + y = attr.toInt(); + + if ((attr = element.attribute("opacity")).isNull()) + return 0; + + if ((opacity = attr.toInt()) < 0 || opacity > TQ_UINT8_MAX) + opacity = OPACITY_OPAQUE; + + + TQString compositeOpName = element.attribute("compositeop"); + KisCompositeOp compositeOp; + + if (compositeOpName.isNull()) { + compositeOp = COMPOSITE_OVER; + } else { + compositeOp = KisCompositeOp(compositeOpName); + } + + if (!compositeOp.isValid()) { + return 0; + } + + if ((attr = element.attribute("visible")).isNull()) + attr = "1"; + + visible = attr == "0" ? false : true; + + if ((attr = element.attribute("locked")).isNull()) + attr = "0"; + + locked = attr == "0" ? false : true; + + // Now find out the layer type and do specific handling + if ((attr = element.attribute("layertype")).isNull()) + return loadPaintLayer(element, img, name, x, y, opacity, visible, locked, compositeOp) ; + + if(attr == "paintlayer") + return loadPaintLayer(element, img, name, x, y, opacity, visible, locked, compositeOp); + + if(attr == "grouplayer") + return loadGroupLayer(element, img, name, x, y, opacity, visible, locked, compositeOp).data(); + + if(attr == "adjustmentlayer") + return loadAdjustmentLayer(element, img, name, x, y, opacity, visible, locked, compositeOp).data(); + + if(attr == "partlayer") + return loadPartLayer(element, img, name, x, y, opacity, visible, locked, compositeOp).data(); + + kdWarning(DBG_AREA_FILE) << "Specified layertype is not recognised\n"; + return 0; +} + + +KisLayerSP KisDoc::loadPaintLayer(const TQDomElement& element, KisImageSP img, + TQString name, TQ_INT32 x, TQ_INT32 y, + TQ_INT32 opacity, bool visible, bool locked, KisCompositeOp compositeOp) +{ + TQString attr; + KisPaintLayerSP layer; + KisColorSpace * cs; + + TQString colorspacename; + TQString profileProductName; + + if ((colorspacename = element.attribute("colorspacename")).isNull()) + cs = img->colorSpace(); + else + // use default profile - it will be replaced later in completLoading + cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(colorspacename,""); + + layer = new KisPaintLayer(img, name, opacity, cs); + Q_CHECK_PTR(layer); + + layer->setCompositeOp(compositeOp); + layer->setVisible(visible); + layer->setLocked(locked); + layer->setX(x); + layer->setY(y); + + if ((element.attribute("filename")).isNull()) + m_layerFilenames[layer.data()] = name; + else + m_layerFilenames[layer.data()] = TQString(element.attribute("filename")); + + if ((attr = element.attribute("hastqmask")).isNull()) + attr = "0"; + + if (attr == "1") { + // We add a tqmask, but we'll fill in the actual tqmask later in completeLoading with the visitor + layer->createMask(); + } + + + // Load exif info + for( TQDomNode node = element.firstChild(); !node.isNull(); node = node.nextSibling() ) + { + TQDomElement e = node.toElement(); + if ( !e.isNull() && e.tagName() == "ExifInfo" ) + { + layer->paintDevice()->exifInfo()->load(e); + } + } + return layer.data(); +} + +KisGroupLayerSP KisDoc::loadGroupLayer(const TQDomElement& element, KisImageSP img, + TQString name, TQ_INT32 x, TQ_INT32 y, TQ_INT32 opacity, bool visible, bool locked, + KisCompositeOp compositeOp) +{ + TQString attr; + KisGroupLayerSP layer; + + layer = new KisGroupLayer(img, name, opacity); + Q_CHECK_PTR(layer); + + layer->setCompositeOp(compositeOp); + layer->setVisible(visible); + layer->setLocked(locked); + layer->setX(x); + layer->setY(y); + + loadLayers(element, img, layer); + + return layer; +} + +KisAdjustmentLayerSP KisDoc::loadAdjustmentLayer(const TQDomElement& element, KisImageSP img, + TQString name, TQ_INT32 x, TQ_INT32 y, TQ_INT32 opacity, bool visible, bool locked, + KisCompositeOp compositeOp) +{ + TQString attr; + KisAdjustmentLayerSP layer; + TQString filtername; + + if ((filtername = element.attribute("filtername")).isNull()) { + // XXX: Invalid adjustmentlayer! We should warn about it! + kdWarning(DBG_AREA_FILE) << "No filter in adjustment layer" << endl; + return 0; + } + + KisFilter * f = KisFilterRegistry::instance()->get(filtername); + if (!f) { + kdWarning(DBG_AREA_FILE) << "No filter for filtername " << filtername << "\n"; + return 0; // XXX: We don't have this filter. We should warn about it! + } + + KisFilterConfiguration * kfc = f->configuration(); + + // We'll load the configuration and the selection later. + layer = new KisAdjustmentLayer(img, name, kfc, 0); + Q_CHECK_PTR(layer); + + layer->setCompositeOp(compositeOp); + layer->setVisible(visible); + layer->setLocked(locked); + layer->setX(x); + layer->setY(y); + layer->setOpacity(opacity); + + if ((element.attribute("filename")).isNull()) + m_layerFilenames[layer.data()] = name; + else + m_layerFilenames[layer.data()] = TQString(element.attribute("filename")); + + return layer; +} + +KisPartLayerSP KisDoc::loadPartLayer(const TQDomElement& element, KisImageSP img, + TQString name, TQ_INT32 /*x*/, TQ_INT32 /*y*/, TQ_INT32 opacity, + bool visible, bool locked, + KisCompositeOp compositeOp) { + KisChildDoc* child = new KisChildDoc(this); + TQString filename(element.attribute("filename")); + TQDomElement partElement = element.namedItem("object").toElement(); + + if (partElement.isNull()) { + kdWarning() << "loadPartLayer failed with partElement isNull" << endl; + return 0; + } + + child->load(partElement); + insertChild(child); + + KisPartLayerSP layer = new KisPartLayerImpl(img, child); + Q_CHECK_PTR(layer); + + layer->setCompositeOp(compositeOp); + layer->setVisible(visible); + layer->setLocked(locked); + layer->setOpacity(opacity); + layer->setName(name); + + return layer; +} + +bool KisDoc::completeSaving(KoStore *store) +{ + TQString uri = url().url(); + TQString location; + bool external = isStoredExtern(); + TQ_INT32 totalSteps = 0; + + if (!m_currentImage) return false; + + totalSteps = (m_currentImage)->nlayers(); + + + setIOSteps(totalSteps + 1); + + // Save the layers data + TQ_UINT32 count=0; + KisSaveVisitor visitor(m_currentImage, store, count); + + if(external) + visitor.setExternalUri(uri); + + m_currentImage->rootLayer()->accept(visitor); + + // saving annotations + // XXX this only saves EXIF and ICC info. This would probably need + // a redesign of the dtd of the chalk file to do this more generally correct + // e.g. have <ANNOTATION> tags or so. + KisAnnotationSP annotation = (m_currentImage)->annotation("exif"); + if (annotation) { + location = external ? TQString() : uri; + location += (m_currentImage)->name() + "/annotations/exif"; + if (store->open(location)) { + store->write(annotation->annotation()); + store->close(); + } + } + if (m_currentImage->getProfile()) { + annotation = m_currentImage->getProfile()->annotation(); + + if (annotation) { + location = external ? TQString() : uri; + location += m_currentImage->name() + "/annotations/icc"; + if (store->open(location)) { + store->write(annotation->annotation()); + store->close(); + } + } + } + + IODone(); + return true; +} + +bool KisDoc::completeLoading(KoStore *store) +{ + TQString uri = url().url(); + TQString location; + bool external = isStoredExtern(); + TQ_INT32 totalSteps = 0; + + totalSteps = (m_currentImage)->nlayers(); + + setIOSteps(totalSteps); + + // Load the layers data + KisLoadVisitor visitor(m_currentImage, store, m_layerFilenames); + + if(external) + visitor.setExternalUri(uri); + + m_currentImage->rootLayer()->accept(visitor); + + // annotations + // exif + location = external ? TQString() : uri; + location += (m_currentImage)->name() + "/annotations/exif"; + if (store->hasFile(location)) { + TQByteArray data; + store->open(location); + data = store->read(store->size()); + store->close(); + (m_currentImage)->addAnnotation(new KisAnnotation("exif", "", data)); + } + // icc profile + location = external ? TQString() : uri; + location += (m_currentImage)->name() + "/annotations/icc"; + if (store->hasFile(location)) { + TQByteArray data; + store->open(location); + data = store->read(store->size()); + store->close(); + (m_currentImage)->setProfile(new KisProfile(data)); + } + + IODone(); + + setModified( false ); + setUndo(true); + return true; +} + +TQWidget* KisDoc::createCustomDocumentWidget(TQWidget *tqparent) +{ + + KisConfig cfg; + + int w = cfg.defImgWidth(); + int h = cfg.defImgHeight(); + + TQSize sz = KisClipboard::instance()->clipSize(); + if (sz.isValid() && sz.width() != 0 && sz.height() != 0) { + w = sz.width(); + h = sz.height(); + } + return new KisCustomImageWidget(tqparent, this, w, h, cfg.defImgResolution(), cfg.workingColorSpace(),"unnamed"); +} + + +KoDocument* KisDoc::hitTest(const TQPoint &pos, const TQWMatrix& matrix) { + KoDocument* doc = super::hitTest(pos, matrix); + if (doc && doc != this) { + // We hit a child document. We will only acknowledge we hit it, if the hit child + // is the currently active parts layer. + KisPartLayerImpl* partLayer + = dynamic_cast<KisPartLayerImpl*>(currentImage()->activeLayer().data()); + + if (!partLayer) + return this; + + if (doc == partLayer->childDoc()->document()) { + return doc; + } + return this; + } + return doc; +} + +void KisDoc::renameImage(const TQString& oldName, const TQString& newName) +{ + (m_currentImage)->setName(newName); + + if (undo()) + addCommand(new KisCommandImageMv(this, this, newName, oldName)); +} + + +KisImageSP KisDoc::newImage(const TQString& name, TQ_INT32 width, TQ_INT32 height, KisColorSpace * colorstrategy) +{ + if (!init()) + return 0; + + setUndo(false); + + KisImageSP img = new KisImage(this, width, height, colorstrategy, name); + Q_CHECK_PTR(img); + connect( img, TQT_SIGNAL( sigImageModified() ), this, TQT_SLOT( slotImageUpdated() )); + + KisPaintLayer *layer = new KisPaintLayer(img, img->nextLayerName(), OPACITY_OPAQUE,colorstrategy); + Q_CHECK_PTR(layer); + + KisColorSpace * cs = KisMetaRegistry::instance()->csRegistry()->getRGB8(); + KisFillPainter painter; + + painter.begin(layer->paintDevice()); + painter.fillRect(0, 0, width, height, KisColor(TQt::white, cs), OPACITY_OPAQUE); + painter.end(); + + img->addLayer(layer, img->rootLayer(), 0); + img->activate(layer); + + m_currentImage = img; + + setUndo(true); + + return img; +} + +bool KisDoc::newImage(const TQString& name, TQ_INT32 width, TQ_INT32 height, KisColorSpace * cs, const KisColor &bgColor, const TQString &imgDescription, const double imgResolution) +{ + if (!init()) + return false; + + KisConfig cfg; + + TQ_UINT8 opacity = OPACITY_OPAQUE;//bgColor.getAlpha(); + KisImageSP img; + KisPaintLayer *layer; + + if (!cs) return false; + + setUndo(false); + + img = new KisImage(this, width, height, cs, name); + Q_CHECK_PTR(img); + connect( img, TQT_SIGNAL( sigImageModified() ), this, TQT_SLOT( slotImageUpdated() )); + img->setResolution(imgResolution, imgResolution); + img->setDescription(imgDescription); + img->setProfile(cs->getProfile()); + + layer = new KisPaintLayer(img, img->nextLayerName(), OPACITY_OPAQUE, cs); + Q_CHECK_PTR(layer); + + KisFillPainter painter; + painter.begin(layer->paintDevice()); + painter.fillRect(0, 0, width, height, bgColor, opacity); + painter.end(); + + TQValueVector<KisPaintDeviceAction *> actions = KisMetaRegistry::instance() -> + csRegistry()->paintDeviceActionsFor(cs); + for (uint i = 0; i < actions.count(); i++) + actions.at(i)->act(layer->paintDevice(), img->width(), img->height()); + + img->setBackgroundColor(bgColor); + img->addLayer(layer, img->rootLayer(), 0); + img->activate(layer); + + m_currentImage = img; + + cfg.defImgWidth(width); + cfg.defImgHeight(height); + cfg.defImgResolution(imgResolution); + + setUndo(true); + + return true; +} + +KoView* KisDoc::createViewInstance(TQWidget* tqparent, const char *name) +{ + KisView * v = new KisView(this, this, tqparent, name); + Q_CHECK_PTR(v); + + return v; +} + +void KisDoc::paintContent(TQPainter& painter, const TQRect& rc, bool transparent, double zoomX, double zoomY) +{ + KisConfig cfg; + TQString monitorProfileName = cfg.monitorProfile(); + KisProfile * profile = KisMetaRegistry::instance()->csRegistry()->getProfileByName(monitorProfileName); + painter.scale(zoomX, zoomY); + TQRect rect = rc & m_currentImage->bounds(); + KisImage::PaintFlags paintFlags; + if (transparent) { + paintFlags = KisImage::PAINT_SELECTION; + } else { + paintFlags = (KisImage::PaintFlags)(KisImage::PAINT_BACKGROUND|KisImage::PAINT_SELECTION); + } + + paintFlags = (KisImage::PaintFlags)(paintFlags | KisImage::PAINT_EMBEDDED_RECT); + + m_currentImage->renderToPainter(rect.left(), rect.top(), rect.right(), rect.bottom(), painter, profile, paintFlags); +} + +void KisDoc::slotImageUpdated() +{ + emit docUpdated(); + setModified(true); +} + +void KisDoc::slotImageUpdated(const TQRect& rect) +{ + emit docUpdated(rect); +} + +void KisDoc::beginMacro(const TQString& macroName) +{ + if (m_undo) { + if (m_macroNestDepth == 0) { + Q_ASSERT(m_currentMacro == 0); + m_currentMacro = new KMacroCommand(macroName); + Q_CHECK_PTR(m_currentMacro); + } + + m_macroNestDepth++; + } +} + +void KisDoc::endMacro() +{ + if (m_undo) { + Q_ASSERT(m_macroNestDepth > 0); + if (m_macroNestDepth > 0) { + m_macroNestDepth--; + + if (m_macroNestDepth == 0) { + Q_ASSERT(m_currentMacro != 0); + + m_cmdHistory->addCommand(m_currentMacro, false); + m_currentMacro = 0; + emit sigCommandExecuted(); + } + } + } +} + +void KisDoc::setCommandHistoryListener(const KisCommandHistoryListener * l) +{ + // Never have more than one instance of a listener around. TQt should prove a Set class for this... + m_undoListeners.removeRef(l); + m_undoListeners.append(l); +} + +void KisDoc::removeCommandHistoryListener(const KisCommandHistoryListener * l) +{ + m_undoListeners.removeRef(l); +} + +KCommand * KisDoc::presentCommand() +{ + return m_cmdHistory->presentCommand(); +} + +void KisDoc::addCommand(KCommand *cmd) +{ + Q_ASSERT(cmd); + + KisCommandHistoryListener* l = 0; + + for (l = m_undoListeners.first(); l; l = m_undoListeners.next()) { + l->notifyCommandAdded(cmd); + } + + setModified(true); + + if (m_undo) { + if (m_currentMacro) + m_currentMacro->addCommand(cmd); + else { + m_cmdHistory->addCommand(cmd, false); + emit sigCommandExecuted(); + } + } else { + kdDebug() << "Deleting command\n"; + delete cmd; + } +} + +void KisDoc::setUndo(bool undo) +{ + m_undo = undo; + if (m_undo && m_cmdHistory->undoLimit() == 50 /*default*/) { + KisConfig cfg; + setUndoLimit( cfg.defUndoLimit() ); + } +} + +TQ_INT32 KisDoc::undoLimit() const +{ + return m_cmdHistory->undoLimit(); +} + +void KisDoc::setUndoLimit(TQ_INT32 limit) +{ + m_cmdHistory->setUndoLimit(limit); +} + +TQ_INT32 KisDoc::redoLimit() const +{ + return m_cmdHistory->redoLimit(); +} + +void KisDoc::setRedoLimit(TQ_INT32 limit) +{ + m_cmdHistory->setRedoLimit(limit); +} + +void KisDoc::slotDocumentRestored() +{ + setModified(false); +} + +void KisDoc::slotCommandExecuted(KCommand *command) +{ + setModified(true); + emit sigCommandExecuted(); + + KisCommandHistoryListener* l = 0; + + for (l = m_undoListeners.first(); l; l = m_undoListeners.next()) { + l->notifyCommandExecuted(command); + } + +} + +void KisDoc::slotUpdate(KisImageSP, TQ_UINT32 x, TQ_UINT32 y, TQ_UINT32 w, TQ_UINT32 h) +{ + TQRect rc(x, y, w, h); + + emit docUpdated(rc); +} + +bool KisDoc::undo() const +{ + return m_undo; +} + +void KisDoc::setIOSteps(TQ_INT32 nsteps) +{ + m_ioProgressTotalSteps = nsteps * 100; + m_ioProgressBase = 0; + emitProgress(0); +} + +void KisDoc::IOCompletedStep() +{ + m_ioProgressBase += 100; +} + +void KisDoc::IODone() +{ + emitProgress(-1); +} + +void KisDoc::slotIOProgress(TQ_INT8 percentage) +{ + KApplication *app = KApplication::kApplication(); + + Q_ASSERT(app); + + if (app->hasPendingEvents()) + app->processEvents(); + + int totalPercentage = ((m_ioProgressBase + percentage) * 100) / m_ioProgressTotalSteps; + + emitProgress(totalPercentage); +} + +KisChildDoc * KisDoc::createChildDoc( const TQRect & rect, KoDocument* childDoc ) +{ + KisChildDoc * ch = new KisChildDoc( this, rect, childDoc ); + insertChild( ch ); + ch->document()->setStoreInternal(true); + return ch; +} + +void KisDoc::prepareForImport() +{ + if (m_nserver == 0) + init(); + setUndo(false); +} + +KisImageSP KisDoc::currentImage() +{ + return m_currentImage; +} + +void KisDoc::setCurrentImage(KisImageSP image) +{ + m_currentImage = image; + setUndo(true); + image->notifyImageLoaded(); + emit loadingFinished(); +} + +void KisDoc::initEmpty() +{ + KisConfig cfg; + KisColorSpace * rgb = KisMetaRegistry::instance()->csRegistry()->getRGB8(); + newImage("", cfg.defImgWidth(), cfg.defImgHeight(), rgb); +} + +#include "kis_doc.moc" + diff --git a/chalk/ui/kis_doc.h b/chalk/ui/kis_doc.h new file mode 100644 index 00000000..47eeaa0f --- /dev/null +++ b/chalk/ui/kis_doc.h @@ -0,0 +1,224 @@ +/* + * Copyright (c) 1999-2000 Matthias Elter <me@kde.org> + * Copyright (c) 2001 Toshitaka Fujioka <fujioka@kde.org> + * Copyright (c) 2002 Patrick Julien <freak@codepimps.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_DOC_H_ +#define KIS_DOC_H_ + +#include <kdebug.h> + +#include <KoDocument.h> + +#include "kis_types.h" +#include "kis_undo_adapter.h" + +#include <koffice_export.h> + +class TQImage; +class TQString; + +class DCOPObject; +class KCommand; + +class KoCommandHistory; +class KMacroCommand; + +class KisProfile; +class KisView; +class KisNameServer; +class KisChildDoc; +class KisColorSpace; +class KisColor; +class KisCompositeOp; + +class KRITACORE_EXPORT KisDoc : public KoDocument, private KisUndoAdapter { + + typedef KoDocument super; + Q_OBJECT + TQ_OBJECT + +public: + KisDoc(TQWidget *tqparentWidget = 0, const char *widgetName = 0, TQObject* tqparent = 0, const char* name = 0, bool singleViewMode = false); + virtual ~KisDoc(); + +public: + // Overide KoDocument + virtual bool wantExportConfirmation() const { return false; }; + virtual bool completeLoading(KoStore *store); + virtual bool completeSaving(KoStore*); + virtual DCOPObject* dcopObject(); + virtual bool initDoc(InitDocFlags flags, TQWidget* tqparentWidget=0); + virtual bool loadOasis( const TQDomDocument&, KoOasisStyles&, const TQDomDocument&, KoStore* ); + virtual bool saveOasis( KoStore*, KoXmlWriter* ); + virtual bool loadChildren( KoStore* store); + virtual bool loadXML(TQIODevice *, const TQDomDocument& doc); + virtual TQCString mimeType() const; + virtual TQWidget* createCustomDocumentWidget(TQWidget *tqparent); + virtual KoDocument* hitTest(const TQPoint &pos, const TQWMatrix& matrix = TQWMatrix()); + + /** + * Draw the image embedded in another KOffice document + * + * XXX: Use of transparent, zoomX and zoomY is not supported + * by Chalk because we appear to be doing our zooming + * elsewhere. This may affect KOffice compatibility. + */ + virtual void paintContent(TQPainter& painter, const TQRect& rect, bool /*transparent*/, double /*zoomX*/, double /*zoomY*/); + + virtual TQDomDocument saveXML(); + +public slots: + + + /** + * Initialize an empty document using default values + * @since 1.5 + */ + virtual void initEmpty(); + +private: // Undo adapter + + virtual void setCommandHistoryListener(const KisCommandHistoryListener *); + virtual void removeCommandHistoryListener(const KisCommandHistoryListener *); + + virtual KCommand * presentCommand(); + virtual void addCommand(KCommand *cmd); + virtual void setUndo(bool undo); + virtual bool undo() const; + virtual void beginMacro(const TQString& macroName); + virtual void endMacro(); + + +public: + + + TQ_INT32 undoLimit() const; + void setUndoLimit(TQ_INT32 limit); + + TQ_INT32 redoLimit() const; + void setRedoLimit(TQ_INT32 limit); + + /** + * Create a new image that has this document as a tqparent and + * replace the current image with this image. + */ + bool newImage(const TQString& name, TQ_INT32 width, TQ_INT32 height, KisColorSpace * cs, const KisColor &bgColor, const TQString &imgDescription, const double imgResolution); + + /** + * Create a new image that has this document as a tqparent and + * replace the current image with this image. + */ + KisImageSP newImage(const TQString& name, TQ_INT32 width, TQ_INT32 height, KisColorSpace * colorstrategy); + + void renameImage(const TQString& oldName, const TQString& newName); + + + /** + * Adds the specified child document to this document; this + * is not done with KoDocument::insertChild() because that + * is protected and cannot be called from KisView. + */ + KisChildDoc * createChildDoc( const TQRect& rect, KoDocument* childDoc ); + + /** + * Makes an otherwise empty document ready for import/export + */ + void prepareForImport(); + + KisImageSP currentImage(); + + /** + * Set the current image to the specified image and turn undo on. + */ + void setCurrentImage(KisImageSP image); + + KisUndoAdapter * undoAdapter() { return this; } + +public slots: + void slotImageUpdated(); + void slotImageUpdated(const TQRect& rect); + void slotDocumentRestored(); + void slotCommandExecuted(KCommand *command); + +signals: + void docUpdated(); + void docUpdated(TQRect rect); + void loadingFinished(); + + /* + * Emitted every time a command is added to the undo history, or executed + * due to an undo or redo action. + */ + void sigCommandExecuted(); + +protected: + // Overide KoDocument + virtual KoView* createViewInstance(TQWidget *tqparent, const char *name); + +protected slots: + // Overide KoDocument + virtual void openExistingFile(const TQString& file); + virtual void openTemplate(const TQString& file); + +private slots: + void slotUpdate(KisImageSP img, TQ_UINT32 x, TQ_UINT32 y, TQ_UINT32 w, TQ_UINT32 h); + void slotIOProgress(TQ_INT8 percentage); + +private: + + TQDomElement saveImage(TQDomDocument& doc, KisImageSP img); + KisImageSP loadImage(const TQDomElement& elem); + void loadLayers(const TQDomElement& element, KisImageSP img, KisGroupLayerSP tqparent); + KisLayerSP loadLayer(const TQDomElement& elem, KisImageSP img); + KisLayerSP loadPaintLayer(const TQDomElement& elem, KisImageSP img, + TQString name, TQ_INT32 x, TQ_INT32 y, TQ_INT32 opacity, bool visible, bool locked, + KisCompositeOp compositeOp); + KisGroupLayerSP loadGroupLayer(const TQDomElement& elem, KisImageSP img, + TQString name, TQ_INT32 x, TQ_INT32 y, TQ_INT32 opacity, bool visible, bool locked, + KisCompositeOp compositeOp); + KisAdjustmentLayerSP loadAdjustmentLayer(const TQDomElement& elem, KisImageSP img, + TQString name, TQ_INT32 x, TQ_INT32 y, TQ_INT32 opacity, bool visible, bool locked, + KisCompositeOp compositeOp); + KisPartLayerSP loadPartLayer(const TQDomElement& elem, KisImageSP img, + TQString name, TQ_INT32 x, TQ_INT32 y, TQ_INT32 opacity, + bool visible, bool locked, KisCompositeOp compositeOp); + bool init(); + + void setIOSteps(TQ_INT32 nsteps); + void IOCompletedStep(); + void IODone(); + +private: + + bool m_undo; + KoCommandHistory *m_cmdHistory; + TQPtrList<KisCommandHistoryListener> m_undoListeners; + KisImageSP m_currentImage; + DCOPObject *m_dcop; + KisNameServer *m_nserver; + KMacroCommand *m_currentMacro; + TQ_INT32 m_macroNestDepth; + TQ_INT32 m_conversionDepth; + int m_ioProgressTotalSteps; + int m_ioProgressBase; + TQMap<KisLayerSP, TQString> m_layerFilenames; // temp storage during load + +}; + +#endif // KIS_DOC_H_ + diff --git a/chalk/ui/kis_doc_iface.cc b/chalk/ui/kis_doc_iface.cc new file mode 100644 index 00000000..50af9898 --- /dev/null +++ b/chalk/ui/kis_doc_iface.cc @@ -0,0 +1,67 @@ +/* This file is part of the KDE project + * Copyright (C) 2002 Laurent Montel <lmontel@mandrakesoft.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_doc_iface.h" +#include <kapplication.h> + +#include "kis_doc.h" +#include "kis_image.h" + +#include <dcopclient.h> + +KisDocIface::KisDocIface( KisDoc *doc_ ) + : KoDocumentIface( doc_ ) +{ + m_doc = doc_; +} + +DCOPRef KisDocIface::currentImage() +{ + KisImage *img = m_doc->currentImage(); + if( !img ) + return DCOPRef(); + else + return DCOPRef( kapp->dcopClient()->appId(), + img->dcopObject()->objId(), + "KisImageIface"); +} + +int KisDocIface::undoLimit () const +{ + return m_doc->undoLimit(); +} + +void KisDocIface::setUndoLimit(int limit) +{ + m_doc->setUndoLimit(limit); +} + +int KisDocIface::redoLimit() const +{ + return m_doc->redoLimit(); +} + +void KisDocIface::setRedoLimit(int limit) +{ + m_doc->setRedoLimit(limit); +} + +void KisDocIface::renameImage(const TQString& oldName, const TQString& newName) +{ + m_doc->renameImage(oldName,newName); +} diff --git a/chalk/ui/kis_doc_iface.h b/chalk/ui/kis_doc_iface.h new file mode 100644 index 00000000..36c71a5f --- /dev/null +++ b/chalk/ui/kis_doc_iface.h @@ -0,0 +1,50 @@ +/* This file is part of the KDE project + * Copyright (C) 2002 Laurent Montel <lmontel@mandrakesoft.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_DOC_IFACE_H +#define KIS_DOC_IFACE_H + +#include <KoViewIface.h> +#include <KoDocumentIface.h> + +#include <dcopref.h> +#include <tqstring.h> +#include <kis_image_iface.h> + +class KisDoc; + +class KisDocIface : virtual public KoDocumentIface +{ + K_DCOP +public: + KisDocIface( KisDoc *doc_ ); +k_dcop: + virtual DCOPRef currentImage(); + + virtual int undoLimit () const; + virtual void setUndoLimit(int limit); + virtual int redoLimit() const; + virtual void setRedoLimit(int limit); + + virtual void renameImage(const TQString& oldName, const TQString& newName); + +private: + KisDoc *m_doc; +}; + +#endif diff --git a/chalk/ui/kis_double_click_event.h b/chalk/ui/kis_double_click_event.h new file mode 100644 index 00000000..c3447602 --- /dev/null +++ b/chalk/ui/kis_double_click_event.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2005 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_DOUBLE_CLICK_EVENT_H_ +#define KIS_DOUBLE_CLICK_EVENT_H_ + +#include "kis_button_event.h" + +class KisDoubleClickEvent : public KisButtonEvent { + typedef KisButtonEvent super; +public: + KisDoubleClickEvent() {} + KisDoubleClickEvent(KisInputDevice device, const KisPoint& pos, const KisPoint& globalPos, double pressure, double xTilt, double yTilt, TQt::ButtonState button, TQt::ButtonState state) : super(DoubleClickEvent, device, pos, globalPos, pressure, xTilt, yTilt, button, state) {} +}; + +#endif // KIS_DOUBLE_CLICK_EVENT_H_ + diff --git a/chalk/ui/kis_double_widget.cc b/chalk/ui/kis_double_widget.cc new file mode 100644 index 00000000..3c13a47e --- /dev/null +++ b/chalk/ui/kis_double_widget.cc @@ -0,0 +1,147 @@ +/* + * kis_double_widget.cc - part of Chalk + * + * Copyright (c) 1999 Carsten Pfeiffer <pfeiffer@kde.org> + * Copyright (c) 2004 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <tqhbox.h> +#include <tqlayout.h> +#include <tqslider.h> + +#include <knuminput.h> + +#include "kis_double_widget.h" + +KisDoubleWidget::KisDoubleWidget(TQWidget* tqparent, const char* name) + : super(tqparent, name) +{ + init(0, 1); +} + +KisDoubleWidget::KisDoubleWidget(double min, double max, TQWidget* tqparent, const char* name) + : super(tqparent, name) +{ + init(min, max); +} + +KisDoubleWidget::~KisDoubleWidget() +{ +} + +void KisDoubleWidget::init(double min, double max) +{ + m_spinBox = new KDoubleSpinBox(min, max, 0.05, 0, 2, this, "spinbox"); + connect(m_spinBox, TQT_SIGNAL(valueChanged(double)), this, TQT_SLOT(setSliderValue(double))); + + m_slider = new TQSlider(static_cast<int>(min * 100 + 0.5), static_cast<int>(max * 100 + 0.5), 1, 0, Qt::Horizontal, this, "sld"); + connect(m_slider, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(sliderValueChanged(int))); + connect(m_slider, TQT_SIGNAL(sliderPressed()), TQT_SIGNAL(sliderPressed())); + connect(m_slider, TQT_SIGNAL(sliderReleased()), TQT_SIGNAL(sliderReleased())); + + m_layout = new TQHBoxLayout(this, 0, -1, "hbox tqlayout"); + + m_layout->addWidget(m_slider); + m_layout->addSpacing(5); + m_layout->addWidget(m_spinBox); + m_layout->addItem(new TQSpacerItem(5,1,TQSizePolicy::Expanding, TQSizePolicy::Minimum)); +} + +double KisDoubleWidget::value() const +{ + return m_spinBox->value(); +} + +void KisDoubleWidget::setValue(double value) +{ + int intValue; + + if (value < 0) { + intValue = static_cast<int>(value * 100 - 0.5); + } else { + intValue = static_cast<int>(value * 100 + 0.5); + } + m_slider->setValue(intValue); +} + +void KisDoubleWidget::setRange(double min, double max) +{ + m_spinBox->setRange(min, max); + m_slider->setRange(static_cast<int>(min * 100 + 0.5), static_cast<int>(max * 100 + 0.5)); +} + +void KisDoubleWidget::setTickmarks(TQSlider::TickSetting tickSetting) +{ + m_slider->setTickmarks(tickSetting); +} + +void KisDoubleWidget::setTickInterval(double value) +{ + m_slider->setTickInterval(static_cast<int>(value * 100 + 0.5)); +} + +double KisDoubleWidget::tickInterval() const +{ + return m_slider->tickInterval() / 100.0; +} + +void KisDoubleWidget::setSliderValue(double value) +{ + int intValue; + + if (value < 0) { + intValue = static_cast<int>(value * 100 - 0.5); + } else { + intValue = static_cast<int>(value * 100 + 0.5); + } + m_slider->setValue(intValue); + emit valueChanged(value); +} + +void KisDoubleWidget::sliderValueChanged(int value) +{ + m_spinBox->setValue(value / 100.0); +} + +void KisDoubleWidget::setPrecision(int precision) +{ + m_spinBox->setPrecision(precision); +} + +void KisDoubleWidget::setLineStep(double step) +{ + m_spinBox->setLineStep(step); + m_slider->setLineStep(static_cast<int>(step * 100)); +} + +void KisDoubleWidget::setPageStep(double step) +{ + m_slider->setPageStep(static_cast<int>(step * 100)); +} + +void KisDoubleWidget::setTracking(bool tracking) +{ + m_slider->setTracking(tracking); +} + +bool KisDoubleWidget::tracking() const +{ + return m_slider->tracking(); +} + +#include "kis_double_widget.moc" + diff --git a/chalk/ui/kis_double_widget.h b/chalk/ui/kis_double_widget.h new file mode 100644 index 00000000..89a425b7 --- /dev/null +++ b/chalk/ui/kis_double_widget.h @@ -0,0 +1,78 @@ +/* + * kis_double_widget.h - part of Chalk + * + * Copyright (c) 1999 Carsten Pfeiffer <pfeiffer@kde.org> + * Copyright (c) 2004 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_DOUBLE_WIDGET_H +#define KIS_DOUBLE_WIDGET_H + +#include <tqwidget.h> +#include <tqslider.h> + +class TQHBoxLayout; +class KDoubleSpinBox; + +class KisDoubleWidget : public TQWidget +{ + Q_OBJECT + TQ_OBJECT + + typedef TQWidget super; +public: + KisDoubleWidget(TQWidget* tqparent = 0, const char* name = 0); + KisDoubleWidget(double min, double max, TQWidget* tqparent = 0, const char* name = 0); + ~KisDoubleWidget(); + + double value() const; + void setRange(double min, double max); + + void setTickmarks(TQSlider::TickSetting tickMarks); + void setTickInterval(double tickInterval); + double tickInterval() const; + + void setPrecision(int precision); + void setLineStep(double step); + void setPageStep(double step); + + void setTracking(bool tracking); + bool tracking() const; + +signals: + void valueChanged(double); + void sliderPressed(); + void sliderReleased(); + +public slots: + void setValue(double value); + +protected slots: + void setSliderValue(double); + void sliderValueChanged(int); + +private: + void init(double min, double max); + +protected: + TQHBoxLayout* m_layout; + TQSlider* m_slider; + KDoubleSpinBox *m_spinBox; +}; + +#endif // KIS_DOUBLE_WIDGET_H + diff --git a/chalk/ui/kis_event.h b/chalk/ui/kis_event.h new file mode 100644 index 00000000..417a9168 --- /dev/null +++ b/chalk/ui/kis_event.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2004 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_EVENT_H_ +#define KIS_EVENT_H_ + +#include <tqevent.h> + +#include "kis_point.h" +#include "kis_input_device.h" + +class KisEvent { +public: + enum enumEventType { + UnknownEvent, + MoveEvent, + ButtonPressEvent, + ButtonReleaseEvent, + DoubleClickEvent + }; + + KisEvent() : m_type(UnknownEvent), m_device(KisInputDevice::unknown()) {} + KisEvent(enumEventType type, KisInputDevice device, const KisPoint& pos, const KisPoint& globalPos, double pressure, double xTilt, double yTilt, TQt::ButtonState state) : m_type(type), m_device(device), m_pos(pos), m_globalPos(globalPos), m_pressure(pressure), m_xTilt(xTilt), m_yTilt(yTilt), m_state(state) {} + + enumEventType type() const { return m_type; } + KisInputDevice device() const { return m_device; } + KisPoint pos() const { return m_pos; } + double x() const { return m_pos.x(); } + double y() const { return m_pos.y(); } + KisPoint globalPos() const { return m_globalPos; } + double pressure() const { return m_pressure; } + double xTilt() const { return m_xTilt; } + double yTilt() const { return m_yTilt; } + TQt::ButtonState state() const { return m_state; } + +protected: + enumEventType m_type; + KisInputDevice m_device; + KisPoint m_pos; + KisPoint m_globalPos; + double m_pressure; + double m_xTilt; + double m_yTilt; + TQt::ButtonState m_state; +}; + +#endif // KIS_EVENT_H_ + diff --git a/chalk/ui/kis_factory.cc b/chalk/ui/kis_factory.cc new file mode 100644 index 00000000..0924420d --- /dev/null +++ b/chalk/ui/kis_factory.cc @@ -0,0 +1,153 @@ +/* + * kis_factory.cc - part of Krayon + * + * Copyright (c) 1999 Matthias Elter <elter@kde.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include <config.h> +#include LCMS_HEADER + +#include <tqstringlist.h> +#include <tqdir.h> + +#include <kdebug.h> +#include <kinstance.h> +#include <kglobal.h> +#include <klocale.h> +#include <kstandarddirs.h> +#include <kiconloader.h> + +#include "kis_aboutdata.h" +#include "kis_resourceserver.h" +#include "kis_paintop_registry.h" +#include "kis_filter_registry.h" +#include "kis_tool_registry.h" +#include "kis_doc.h" +#include "kis_brush.h" +#include "kis_imagepipe_brush.h" +#include "kis_gradient.h" +#include "kis_pattern.h" +#include "kis_palette.h" +#include <kogradientmanager.h> + +#include "kis_factory.h" + +KAboutData* KisFactory::s_aboutData = 0; +KInstance* KisFactory::s_instance = 0; + + + +KisFactory::KisFactory( TQObject* tqparent, const char* name ) + : KoFactory( tqparent, name ) +{ + s_aboutData = newChalkAboutData(); + + (void)instance(); + + // Load extension modules and plugins + KisToolRegistry::instance(); + KisPaintOpRegistry::instance(); + KisFilterRegistry::instance(); + KisResourceServerRegistry::instance(); + + + +} + +KisFactory::~KisFactory() +{ + delete s_aboutData; + s_aboutData = 0L; + delete s_instance; + s_instance = 0L; +} + +/** + * Create the document + */ +KParts::Part* KisFactory::createPartObject( TQWidget *tqparentWidget, + const char *widgetName, TQObject* tqparent, + const char* name, const char* classname, const TQStringList & ) +{ + bool bWantKoDocument = ( strcmp( classname, "KoDocument" ) == 0 ); + + KisDoc *doc = new KisDoc( tqparentWidget, + widgetName, tqparent, name, !bWantKoDocument ); + Q_CHECK_PTR(doc); + + if ( !bWantKoDocument ) + doc->setReadWrite( false ); + + return doc; +} + + +KAboutData* KisFactory::aboutData() +{ + return s_aboutData; +} + +KInstance* KisFactory::instance() +{ + TQString homedir = getenv("HOME"); + + if ( !s_instance ) + { + s_instance = new KInstance(s_aboutData); + Q_CHECK_PTR(s_instance); + + s_instance->dirs()->addResourceType("chalk_template", KStandardDirs::kde_default("data") + "chalk/templates"); + + // XXX: Are these obsolete? + s_instance->dirs()->addResourceType("kis", KStandardDirs::kde_default("data") + "chalk/"); + + s_instance->dirs()->addResourceType("kis_pics", KStandardDirs::kde_default("data") + "chalk/pics/"); + + s_instance->dirs()->addResourceType("kis_images", KStandardDirs::kde_default("data") + "chalk/images/"); + + s_instance->dirs()->addResourceType("toolbars", KStandardDirs::kde_default("data") + "koffice/toolbar/"); + + // Create spec + + s_instance->dirs()->addResourceType("kis_brushes", KStandardDirs::kde_default("data") + "chalk/brushes/"); + s_instance->dirs()->addResourceDir("kis_brushes", "/usr/share/create/brushes/gimp"); + s_instance->dirs()->addResourceDir("kis_brushes", TQDir::homeDirPath() + TQString("/.create/brushes/gimp")); + + s_instance->dirs()->addResourceType("kis_patterns", KStandardDirs::kde_default("data") + "chalk/patterns/"); + s_instance->dirs()->addResourceDir("kis_patterns", "/usr/share/create/patterns/gimp"); + s_instance->dirs()->addResourceDir("kis_patterns", TQDir::homeDirPath() + TQString("/.create/patterns/gimp")); + + s_instance->dirs()->addResourceType("kis_gradients", KStandardDirs::kde_default("data") + "chalk/gradients/"); + s_instance->dirs()->addResourceDir("kis_gradients", "/usr/share/create/gradients/gimp"); + s_instance->dirs()->addResourceDir("kis_gradients", TQDir::homeDirPath() + TQString("/.create/gradients/gimp")); + + s_instance->dirs()->addResourceType("kis_profiles", KStandardDirs::kde_default("data") + "chalk/profiles/"); + s_instance->dirs()->addResourceDir("kis_profiles", "/usr/share/color/icc"); + s_instance->dirs()->addResourceDir("kis_profiles", TQDir::homeDirPath() + TQString("/.icc")); + s_instance->dirs()->addResourceDir("kis_profiles", TQDir::homeDirPath() + TQString("/.color/icc")); + + s_instance->dirs()->addResourceType("kis_palettes", KStandardDirs::kde_default("data") + "chalk/palettes/"); + s_instance->dirs()->addResourceDir("kis_palettes", "/usr/share/create/swatches"); + s_instance->dirs()->addResourceDir("kis_palettes", TQDir::homeDirPath() + TQString("/.create/swatches")); + + // Tell the iconloader about share/apps/koffice/icons + s_instance->iconLoader()->addAppDir("koffice"); + } + + return s_instance; +} + +#include "kis_factory.moc" diff --git a/chalk/ui/kis_factory.h b/chalk/ui/kis_factory.h new file mode 100644 index 00000000..d20070c5 --- /dev/null +++ b/chalk/ui/kis_factory.h @@ -0,0 +1,59 @@ +/* + * kis_factory.h - part of Krayon + * + * Copyright (c) 1999 Matthias Elter <elter@kde.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __kis_factory_h__ +#define __kis_factory_h__ + +#include <tqptrlist.h> + +#include <kparts/plugin.h> + +#include <KoFactory.h> + +#include <koffice_export.h> + +class KInstance; +class KAboutData; + +class KRITACORE_EXPORT KisFactory : public KoFactory +{ + Q_OBJECT + TQ_OBJECT + +public: + KisFactory( TQObject* tqparent = 0, const char* name = 0 ); + ~KisFactory(); + + virtual KParts::Part *createPartObject(TQWidget *tqparentWidget = 0, + const char *widgetName = 0, + TQObject *tqparent = 0, + const char *name = 0, + const char *classname = "KoDocument", + const TQStringList &args = TQStringList() ); + + static KAboutData *aboutData(); + static KInstance *instance(); + +private: + static KInstance *s_instance; + static KAboutData *s_aboutData; +}; + +#endif diff --git a/chalk/ui/kis_filter_manager.cc b/chalk/ui/kis_filter_manager.cc new file mode 100644 index 00000000..a21f49aa --- /dev/null +++ b/chalk/ui/kis_filter_manager.cc @@ -0,0 +1,408 @@ +/* + * Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org> + * Copyright (c) 2007 Benjamin Schleimer <bensch128@yahoo.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "tqsignalmapper.h" +#include <tqlayout.h> +#include <tqframe.h> +#include <tqcursor.h> +#include <tqapplication.h> +#include <kmessagebox.h> +#include <kguiitem.h> + +#include <kis_cursor.h> +#include "kaction.h" + +#include "kis_part_layer.h" +#include "kis_id.h" +#include "kis_view.h" +#include "kis_doc.h" +#include "kis_filter.h" +#include "kis_layer.h" +#include "kis_paint_device.h" +#include "kis_paint_layer.h" +#include "kis_filter_manager.h" +#include "kis_filter_config_widget.h" +#include "kis_previewwidget.h" +#include "kis_previewdialog.h" +#include "kis_filter_registry.h" +#include "kis_transaction.h" +#include "kis_undo_adapter.h" +#include "kis_previewdialog.h" +#include "kis_previewwidget.h" +#include "kis_painter.h" +#include "kis_selection.h" +#include "kis_id.h" +#include "kis_canvas_subject.h" +#include "kis_doc.h" +#include "kis_transaction.h" +#include <kis_progress_display_interface.h> + +KisFilterManager::KisFilterManager(KisView * view, KisDoc * doc) + : m_view(view), + m_doc(doc) +{ + // XXX: Store & restore last filter & last filter configuration in session settings + m_reapplyAction = 0; + m_lastFilterConfig = 0; + m_lastDialog = 0; + m_lastFilter = 0; + m_lastWidget = 0; + + m_filterMapper = new TQSignalMapper(this); + + connect(m_filterMapper, TQT_SIGNAL(mapped(int)), this, TQT_SLOT(slotApplyFilter(int))); + +} + +KisFilterManager::~KisFilterManager() +{ + //delete m_reapplyAction; + //delete m_lastFilterConfig; + //delete m_filterMapper; +} + +void KisFilterManager::setup(KActionCollection * ac) +{ + KisFilter * f = 0; + int i = 0; + + // Only create the submenu's we've actually got filters for. + // XXX: Make this list extensible after 1.5 + + KActionMenu * other = 0; + KActionMenu * am = 0; + + m_filterList = KisFilterRegistry::instance()->listKeys(); + + for ( KisIDList::Iterator it = m_filterList.begin(); it != m_filterList.end(); ++it ) { + f = KisFilterRegistry::instance()->get(*it); + if (!f) break; + + TQString s = f->menuCategory(); + if (s == "adjust" && !m_filterActionMenus.tqfind("adjust")) { + am = new KActionMenu(i18n("Adjust"), ac, "adjust_filters"); + m_filterActionMenus.insert("adjust", am); + } + + else if (s == "artistic" && !m_filterActionMenus.tqfind("artistic")) { + am = new KActionMenu(i18n("Artistic"), ac, "artistic_filters"); + m_filterActionMenus.insert("artistic", am); + } + + else if (s == "blur" && !m_filterActionMenus.tqfind("blur")) { + am = new KActionMenu(i18n("Blur"), ac, "blur_filters"); + m_filterActionMenus.insert("blur", am); + } + + else if (s == "colors" && !m_filterActionMenus.tqfind("colors")) { + am = new KActionMenu(i18n("Colors"), ac, "color_filters"); + m_filterActionMenus.insert("colors", am); + } + + else if (s == "decor" && !m_filterActionMenus.tqfind("decor")) { + am = new KActionMenu(i18n("Decor"), ac, "decor_filters"); + m_filterActionMenus.insert("decor", am); + } + + else if (s == "edge" && !m_filterActionMenus.tqfind("edge")) { + am = new KActionMenu(i18n("Edge Detection"), ac, "edge_filters"); + m_filterActionMenus.insert("edge", am); + } + + else if (s == "emboss" && !m_filterActionMenus.tqfind("emboss")) { + am = new KActionMenu(i18n("Emboss"), ac, "emboss_filters"); + m_filterActionMenus.insert("emboss", am); + } + + else if (s == "enhance" && !m_filterActionMenus.tqfind("enhance")) { + am = new KActionMenu(i18n("Enhance"), ac, "enhance_filters"); + m_filterActionMenus.insert("enhance", am); + } + + else if (s == "map" && !m_filterActionMenus.tqfind("map")) { + am = new KActionMenu(i18n("Map"), ac, "map_filters"); + m_filterActionMenus.insert("map", am); + } + + else if (s == "nonphotorealistic" && !m_filterActionMenus.tqfind("nonphotorealistic")) { + am = new KActionMenu(i18n("Non-photorealistic"), ac, "nonphotorealistic_filters"); + m_filterActionMenus.insert("nonphotorealistic", am); + } + + else if (s == "other" && !m_filterActionMenus.tqfind("other")) { + other = new KActionMenu(i18n("Other"), ac, "misc_filters"); + m_filterActionMenus.insert("other", other); + } + + } + + m_reapplyAction = new KAction(i18n("Apply Filter Again"), + "Ctrl+Shift+F", + this, TQT_SLOT(slotApply()), + ac, "filter_apply_again"); + + m_reapplyAction->setEnabled(false); + + f = 0; + i = 0; + for ( KisIDList::Iterator it = m_filterList.begin(); it != m_filterList.end(); ++it ) { + f = KisFilterRegistry::instance()->get(*it); + + if (!f) break; + + // Create action + KAction * a = new KAction(f->menuEntry(), 0, m_filterMapper, TQT_SLOT(map()), ac, + TQString("chalk_filter_%1").tqarg((*it) . id()).ascii()); + + // Add action to the right submenu + KActionMenu * m = m_filterActionMenus.tqfind( f->menuCategory() ); + if (m) { + m->insert(a); + } + else { + if (!other) { + other = new KActionMenu(i18n("Other"), ac, "misc_filters"); + m_filterActionMenus.insert("other", am); + } + other->insert(a); + } + + // Add filter to list of filters for mapper + m_filterMapper->setMapping( a, i ); + + m_filterActions.append( a ); + ++i; + } +} + +void KisFilterManager::updateGUI() +{ + KisImageSP img = m_view->currentImg(); + if (!img) return; + + KisLayerSP layer = img->activeLayer(); + if (!layer) return; + + KisPartLayer * partLayer = dynamic_cast<KisPartLayer*>(layer.data()); + + bool enable = !(layer->locked() || !layer->visible() || partLayer); + KisPaintLayerSP player = dynamic_cast<KisPaintLayer*>( layer.data()); + if(!player) + { + enable = false; + } + m_reapplyAction->setEnabled(m_lastFilterConfig); + if (m_lastFilterConfig) + m_reapplyAction->setText(i18n("Apply Filter Again") + ": " + + KisFilterRegistry::instance()->get(m_lastFilterConfig->name())->id().name()); + else + m_reapplyAction->setText(i18n("Apply Filter Again")); + + KAction * a; + int i = 0; + for (a = m_filterActions.first(); a; a = m_filterActions.next() , i++) { + KisFilter* filter = KisFilterRegistry::instance()->get(m_filterList[i]); + if(player && filter->workWith( player->paintDevice()->colorSpace())) + { + a->setEnabled(enable); + } else { + a->setEnabled(false); + } + } + +} + +void KisFilterManager::slotApply() +{ + apply(); +} + +bool KisFilterManager::apply() +{ + if (!m_lastFilter) return false; + + KisImageSP img = m_view->currentImg(); + if (!img) return false; + + KisPaintDeviceSP dev = img->activeDevice(); + if (!dev) return false; + + TQApplication::setOverrideCursor( KisCursor::waitCursor() ); + + //Apply the filter + m_lastFilterConfig = m_lastFilter->configuration(m_lastWidget); + + TQRect r1 = dev->extent(); + TQRect r2 = img->bounds(); + + // Filters should work only on the visible part of an image. + TQRect rect = r1.intersect(r2); + + if (dev->hasSelection()) { + TQRect r3 = dev->selection()->selectedExactRect(); + rect = rect.intersect(r3); + } + + m_lastFilter->enableProgress(); + + m_view->progressDisplay()->setSubject(m_lastFilter, true, true); + m_lastFilter->setProgressDisplay( m_view->progressDisplay()); + + KisTransaction * cmd = 0; + if (img->undo()) cmd = new KisTransaction(m_lastFilter->id().name(), dev); + + m_lastFilter->process(dev, dev, m_lastFilterConfig, rect); + m_reapplyAction->setEnabled(m_lastFilterConfig); + if (m_lastFilterConfig) + m_reapplyAction->setText(i18n("Apply Filter Again") + ": " + + KisFilterRegistry::instance()->get(m_lastFilterConfig->name())->id().name()); + + else + m_reapplyAction->setText(i18n("Apply Filter Again")); + + m_lastFilter->disableProgress(); + TQApplication::restoreOverrideCursor(); + + + if (m_lastFilter->cancelRequested()) { + delete m_lastFilterConfig; + if (cmd) { + cmd->unexecute(); + delete cmd; + } + return false; + + } else { + if (dev->tqparentLayer()) dev->tqparentLayer()->setDirty(rect); + m_doc->setModified(true); + if (img->undo() && cmd) img->undoAdapter()->addCommand(cmd); + return true; + } +} + +void KisFilterManager::slotApplyFilter(int i) +{ + KisPreviewDialog * oldDialog = m_lastDialog; + KisFilterConfiguration * oldConfig = m_lastFilterConfig; + KisFilter * oldFilter = m_lastFilter; + + m_lastFilter = KisFilterRegistry::instance()->get(m_filterList[i]); + + if (!m_lastFilter) { + m_lastFilter = oldFilter; + return; + } + + KisImageSP img = m_view->currentImg(); + if (!img) return; + + KisPaintDeviceSP dev = img->activeDevice(); + if (!dev) return; + + if (dev->colorSpace()->willDegrade(m_lastFilter->colorSpaceIndependence())) { + // Warning bells! + if (m_lastFilter->colorSpaceIndependence() == TO_LAB16) { + if (KMessageBox::warningContinueCancel(m_view, + i18n("The %1 filter will convert your %2 data to 16-bit L*a*b* and vice versa. ") + .tqarg(m_lastFilter->id().name()) + .tqarg(dev->colorSpace()->id().name()), + i18n("Filter Will Convert Your Layer Data"), + KGuiItem(i18n("Continue")), + "lab16degradation") != KMessageBox::Continue) return; + + } + else if (m_lastFilter->colorSpaceIndependence() == TO_RGBA8) { + if (KMessageBox::warningContinueCancel(m_view, + i18n("The %1 filter will convert your %2 data to 8-bit RGBA and vice versa. ") + .tqarg(m_lastFilter->id().name()) + .tqarg(dev->colorSpace()->id().name()), + i18n("Filter Will Convert Your Layer Data"), + KGuiItem(i18n("Continue")), + "rgba8degradation") != KMessageBox::Continue) return; + } + } + + m_lastFilter->disableProgress(); + + // Create the config dialog + m_lastDialog = new KisPreviewDialog(m_view, m_lastFilter->id().name().ascii(), true, m_lastFilter->id().name()); + Q_CHECK_PTR(m_lastDialog); + m_lastWidget = m_lastFilter->createConfigurationWidget( (TQWidget*)m_lastDialog->container(), dev ); + + bool accepted = true; + + if( m_lastWidget != 0) + { + connect(m_lastWidget, TQT_SIGNAL(sigPleaseUpdatePreview()), this, TQT_SLOT(slotConfigChanged())); + + m_lastDialog->previewWidget()->slotSetDevice( dev ); + + connect(m_lastDialog->previewWidget(), TQT_SIGNAL(updated()), this, TQT_SLOT(refreshPreview())); + + TQGridLayout *widgetLayout = new TQGridLayout((TQWidget *)m_lastDialog->container(), 1, 1); + + widgetLayout->addWidget(m_lastWidget, 0 , 0); + + m_lastDialog->container()->setMinimumSize(m_lastWidget->tqminimumSize()); + + refreshPreview(); + + if(m_lastDialog->exec() == TQDialog::Rejected ) + { + accepted = false; + } + } + + if (!accepted || !apply()) { + // Override the old configuration + m_lastFilterConfig = oldConfig; + m_lastDialog = oldDialog; + m_lastFilter = oldFilter; + } else { + delete oldDialog; + delete oldConfig; + } + +} + +void KisFilterManager::slotConfigChanged() +{ + if( m_lastDialog == 0 ) + return; + if(m_lastDialog->previewWidget()->getAutoUpdate()) + { + refreshPreview(); + } else { + m_lastDialog->previewWidget()->needUpdate(); + } +} + + +void KisFilterManager::refreshPreview( ) +{ + if( m_lastDialog == 0 ) return; + + KisFilterConfiguration* config = m_lastFilter->configuration(m_lastWidget); + + // The preview widget is in charge of running the filter so it can optimize the performance + m_lastDialog->previewWidget()->runFilter(m_lastFilter, config); +} + + +#include "kis_filter_manager.moc" diff --git a/chalk/ui/kis_filter_manager.h b/chalk/ui/kis_filter_manager.h new file mode 100644 index 00000000..beaf66a2 --- /dev/null +++ b/chalk/ui/kis_filter_manager.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _KIS_FILTER_MANAGER_ +#define _KIS_FILTER_MANAGER_ + +#include "tqdict.h" +#include "tqobject.h" +#include "tqptrlist.h" +#include "tqsignalmapper.h" +#include "kactionclasses.h" +#include "kis_image.h" +#include "kis_selection.h" + +#include <koffice_export.h> + +class KAction; +class KisView; +class KisDoc; +class KisFilter; +class KisFilterConfiguration; +class KAction; +class KActionCollection; +class KisPreviewDialog; + +/** + * Create all the filter actions for the specified view and implement re-apply filter + */ +class KRITACORE_EXPORT KisFilterManager : public TQObject { + + Q_OBJECT + TQ_OBJECT + +public: + + KisFilterManager(KisView * tqparent, KisDoc * doc); + ~KisFilterManager(); + + void setup(KActionCollection * ac); + void updateGUI(); + + + bool apply(); + +protected slots: + + void slotApply(); + void slotConfigChanged(); + void slotApplyFilter(int); + void refreshPreview(); + +private: + + KisView * m_view; + KisDoc * m_doc; + + KAction * m_reapplyAction; + + TQPtrList<KAction> m_filterActions; + + KisFilterConfiguration * m_lastFilterConfig; + KisFilter * m_lastFilter; + KisPreviewDialog * m_lastDialog; + KisFilterConfigWidget * m_lastWidget; + + KisIDList m_filterList; // Map the actions in the signalmapper to the filters + TQSignalMapper * m_filterMapper; + + TQDict<KActionMenu> m_filterActionMenus; +}; + +#endif diff --git a/chalk/ui/kis_filters_listview.cc b/chalk/ui/kis_filters_listview.cc new file mode 100644 index 00000000..788a787d --- /dev/null +++ b/chalk/ui/kis_filters_listview.cc @@ -0,0 +1,250 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005 Cyrille Berger <cberger@cberger.net> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "kis_filters_listview.h" + +#include <tqapplication.h> +#include "tqtimer.h" +#include "tqpainter.h" +#include "tqpixmap.h" + +#include <kglobalsettings.h> + +#include "kis_types.h" +#include "kis_paint_device.h" +#include "kis_cursor.h" +#include "kis_image.h" +#include "kis_paint_layer.h" +#include "kis_group_layer.h" +#include "kis_filter.h" +#include "kis_filter_strategy.h" +#include "kis_thread_pool.h" + +// ------------------------------------------------ + +KisFiltersThumbnailThread::KisFiltersThumbnailThread(TQIconView * tqparent, KisFiltersIconViewItem * iconItem, KisFilterConfiguration * config, KisFilter * filter, KisPaintDeviceSP dev, const TQRect & bounds, KisProfile * profile) + : m_parent(tqparent) + , m_iconItem(iconItem) + , m_config(config) + , m_filter(filter) + , m_dev(dev) + , m_bounds(bounds) + , m_profile(profile) +{ +} + +KisFiltersThumbnailThread::~KisFiltersThumbnailThread() +{ + m_iconItem->resetThread(); +} + +void KisFiltersThumbnailThread::run() +{ + if (m_canceled) return; + + KisPaintDeviceSP thumbPreview = new KisPaintDevice(*m_dev); + m_filter->disableProgress(); + m_filter->process(thumbPreview, thumbPreview, m_config, m_bounds); + + if (!m_canceled) { + m_pixmap = thumbPreview->convertToTQImage(m_profile); + + tqApp->postEvent(m_parent, new KisThumbnailDoneEvent (m_iconItem, m_pixmap)); + + } +} + +TQPixmap KisFiltersThumbnailThread::pixmap() +{ + return m_pixmap; +} + +void KisFiltersThumbnailThread::cancel() +{ + m_canceled = true; + m_filter->cancel(); + +} + + +// ------------------------------------------------ + +KisFiltersIconViewItem::KisFiltersIconViewItem(TQIconView * tqparent, const TQString & text, const TQPixmap & icon, + KisID id, KisFilter* filter, KisFilterConfiguration* filterConfig, + KisPaintDeviceSP thumb, const TQRect & bounds, KisProfile * profile) + : TQIconViewItem(tqparent, text, icon) + , m_id(id) + , m_filter(filter) + , m_filterconfig(filterConfig) +{ + m_thread = new KisFiltersThumbnailThread(tqparent, this, filterConfig, filter, thumb, bounds, profile); +} + +KisFiltersIconViewItem::~KisFiltersIconViewItem() +{ + if (m_thread) m_thread->cancel(); +} + + +// ------------------------------------------------ + +KisFiltersListView::KisFiltersListView(TQWidget* tqparent, bool filterForAdjustmentLayers, const char* name) + : KIconView(tqparent, name) + , m_original(0) + , m_profile(0) + , m_filterForAdjustmentLayers(filterForAdjustmentLayers) +{ + init(); +} + +KisFiltersListView::KisFiltersListView(TQWidget * tqparent, const char * name, WFlags f, bool filterForAdjustmentLayers) + : KIconView(tqparent, name, f) + , m_original(0) + , m_profile(0) + , m_filterForAdjustmentLayers(filterForAdjustmentLayers) +{ + init(); +} + +KisFiltersListView::KisFiltersListView(KisLayerSP layer, TQWidget* tqparent, bool filterForAdjustmentLayers, const char * name) + : KIconView(tqparent, name) + , m_original(0) + , m_profile(0) + , m_filterForAdjustmentLayers(filterForAdjustmentLayers) +{ + KisPaintLayer* pl = dynamic_cast<KisPaintLayer*>(layer.data()); + if(pl != 0) + { + m_original = pl->paintDevice(); + buildPreview(); + } + init(); +} + +KisFiltersListView::KisFiltersListView(KisPaintDeviceSP device, TQWidget* tqparent, bool filterForAdjustmentLayers, const char * name) + : KIconView(tqparent, name) + , m_original(device) + , m_profile(0) + , m_filterForAdjustmentLayers(filterForAdjustmentLayers) +{ + buildPreview(); + init(); +} + +void KisFiltersListView::init() +{ + setCaption(i18n("Filters List")); + setItemsMovable(false); + setSelectionMode(TQIconView::Single); + tqsetSizePolicy(TQSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Expanding )); + setMinimumWidth(160); + +} + +void KisFiltersListView::setLayer(KisLayerSP layer) { + KisPaintLayer* pl = dynamic_cast<KisPaintLayer*>(layer.data()); + if(pl == 0) + return; + KisPaintDeviceSP npd = pl->paintDevice(); + if(npd!= m_original) + { + m_original = npd; + buildPreview(); + } +} + +void KisFiltersListView::setCurrentFilter(KisID filter) +{ + setCurrentItem(tqfindItem(filter.name())); +} + +void KisFiltersListView::buildPreview() +{ + TQTime t; + if(m_original== 0) + return; + + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + t.start(); + m_thumb = m_original->createThumbnailDevice(150, 150); + + t.start(); + TQRect bounds = m_thumb->exactBounds(); + TQPixmap pm(bounds.width(), bounds.height()); + TQPainter gc(&pm); + gc.fillRect(0, 0, bounds.width(), bounds.height(), backgroundColor()); + gc.end(); + + t.start(); + KisIDList l = KisFilterRegistry::instance()->listKeys(); + KisIDList::iterator it; + it = l.begin(); + // Iterate over the list of filters + for (it = l.begin(); it != l.end(); ++it) { + KisFilterSP f = KisFilterRegistry::instance()->get(*it); + // Check if filter support the preview and work with the current colorspace + if (f->supportsPreview() && f->workWith( m_original->colorSpace() ) ) { + + if (m_filterForAdjustmentLayers) { + kdDebug() << "We're filtering for adj layers, and this filter (" << f->id().name() << ") supports them: " << f->supportsAdjustmentLayers() << endl; + if(!f->supportsAdjustmentLayers()) continue; + } + std::list<KisFilterConfiguration*> configlist = f->listOfExamplesConfiguration(m_thumb); + // apply the filter for each of example of configuration + for(std::list<KisFilterConfiguration*>::iterator itc = configlist.begin(); + itc != configlist.end(); + itc++) + { + KisFiltersIconViewItem * icon = new KisFiltersIconViewItem( this, (*it).name(), pm, *it, f, *itc, m_thumb, bounds, m_profile ); + //KisThreadPool::instance()->enqueue(icon->thread()); + icon->thread()->runDirectly(); + } + } + } + TQApplication::restoreOverrideCursor(); +} + + +void KisFiltersListView::customEvent(TQCustomEvent * e) +{ + KisThumbnailDoneEvent * ev = dynamic_cast<KisThumbnailDoneEvent *>(e); + if (ev) { + TQPixmap * p = ev->m_iconItem->pixmap(); + TQImage img = ev->m_image; + int x, y; + + if (p->width() > img.width()) + x = (p->width() - img.width()) / 2; + else + x = 0; + if (p->height() > img.height()) + y = (p->height() - img.height()) / 2; + else + y = 0; + + TQPainter gc(p); + gc.drawImage(TQPoint(x,y), img); + gc.end(); + + //ev->m_iconItem->setPixmap(TQPixmap(*p)); + arrangeItemsInGrid(); + } +} diff --git a/chalk/ui/kis_filters_listview.h b/chalk/ui/kis_filters_listview.h new file mode 100644 index 00000000..c4979e25 --- /dev/null +++ b/chalk/ui/kis_filters_listview.h @@ -0,0 +1,143 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005 Cyrille Berger <cberger@cberger.net> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#ifndef _KIS_FILTERS_LIST_VIEW_H_ +#define _KIS_FILTERS_LIST_VIEW_H_ + +#include <tqevent.h> + +#include <kiconview.h> + +#include "kis_id.h" +#include "kis_types.h" +#include "kis_layer.h" +#include "kis_paint_device.h" +#include "kis_thread.h" + +class KisView; +class KisFilter; +class KisFilterConfiguration; +class KisPreviewView; +class KisFiltersIconViewItem; +class KisFiltersListView; +class KisThreadPool; + +class KisThumbnailDoneEvent : public TQCustomEvent +{ +public: + + KisThumbnailDoneEvent(KisFiltersIconViewItem * iconItem, const TQImage & img) + : TQCustomEvent(TQEvent::User + 1969) + , m_iconItem(iconItem) + , m_image(img) {}; + + KisFiltersIconViewItem * m_iconItem; + TQImage m_image; + +}; + + +class KisFiltersThumbnailThread : public KisThread +{ +public: + + KisFiltersThumbnailThread(TQIconView * tqparent, + KisFiltersIconViewItem * iconItem, + KisFilterConfiguration * config, KisFilter * filter, + KisPaintDeviceSP dev, const TQRect & bounds, + KisProfile * profile); + + ~KisFiltersThumbnailThread(); + + virtual void run(); + TQPixmap pixmap(); + void cancel(); + +private: + TQIconView * m_parent; + KisFiltersIconViewItem * m_iconItem; + KisFilterConfiguration * m_config; + KisFilter * m_filter; + KisPaintDeviceSP m_dev; + const TQRect m_bounds; + KisProfile * m_profile; + TQImage m_pixmap; +}; + +class KisFiltersIconViewItem : public TQIconViewItem { +public: + KisFiltersIconViewItem( TQIconView * tqparent, const TQString & text, const TQPixmap & icon, + KisID id, KisFilter* filter, KisFilterConfiguration* filterConfig, + KisPaintDeviceSP thumb, const TQRect & bounds, KisProfile * profile); + + virtual ~KisFiltersIconViewItem(); + KisID id() { return m_id; } + KisFilter* filter() { return m_filter; } + void setFilterConfiguration(KisFilterConfiguration* fc) { m_filterconfig = fc; } + + void resetThread() { m_thread = 0; }; + KisThread * thread() { return m_thread; } + +private: + KisID m_id; + KisFilter* m_filter; + KisFilterConfiguration* m_filterconfig; + KisFiltersThumbnailThread * m_thread; +}; + +class KisFiltersListView : public KIconView { + +public: + explicit KisFiltersListView(TQWidget * tqparent = 0, const char * name = 0, WFlags f = 0, bool filterForAdjustmentLayers = false); + KisFiltersListView(TQWidget* tqparent, bool filterForAdjustmentLayers = false, const char* name = 0); + KisFiltersListView(KisLayerSP layer, TQWidget* tqparent, bool filterForAdjustmentLayers = false, const char * name = 0) KDE_DEPRECATED; + KisFiltersListView(KisPaintDeviceSP layer, TQWidget* tqparent, bool filterForAdjustmentLayers = false, const char * name = 0); + + virtual void customEvent(TQCustomEvent *); + + private: + + void init(); + +public: + void setLayer(KisLayerSP layer) KDE_DEPRECATED; + void setProfile(KisProfile * profile) { m_profile = profile; }; + + inline void setPaintDevice(KisPaintDeviceSP pd) { + if( pd != m_original) + { + m_original = pd; + buildPreview(); + } + } + void buildPreview(); + void setCurrentFilter(KisID filter); + +private: + + KisPaintDeviceSP m_original; + KisImageSP m_imgthumb; + KisPaintDeviceSP m_thumb; + KisProfile * m_profile; + KisThreadPool * threadPool; + bool m_filterForAdjustmentLayers; +}; + +#endif diff --git a/chalk/ui/kis_gradient_chooser.cc b/chalk/ui/kis_gradient_chooser.cc new file mode 100644 index 00000000..7e416ea1 --- /dev/null +++ b/chalk/ui/kis_gradient_chooser.cc @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2004 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include <klocale.h> +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqpushbutton.h> + +#include <kdialogbase.h> + +#include <koIconChooser.h> +#include <kis_view.h> + +#include "kis_global.h" +#include "kis_icon_item.h" +#include "kis_gradient.h" +#include "kis_autogradient.h" + +#include "kis_gradient_chooser.h" + +KisCustomGradientDialog::KisCustomGradientDialog(KisView * view, TQWidget * tqparent, const char *name) + : KDialogBase(tqparent, name, false, i18n("Custom Gradient"), Close) +{ + m_page = new KisAutogradient(this, "autogradient", i18n("Custom Gradient")); + setMainWidget(m_page); + connect(m_page, TQT_SIGNAL(activatedResource(KisResource *)), view, TQT_SLOT(gradientActivated(KisResource*))); +} + +KisGradientChooser::KisGradientChooser(KisView * view, TQWidget *tqparent, const char *name) : super(tqparent, name) +{ + m_lbName = new TQLabel(this); + + m_customGradient = new TQPushButton(i18n("Custom Gradient..."), this, "custom gradient button"); + + KisCustomGradientDialog * autogradient = new KisCustomGradientDialog(view, this, "autogradient"); + connect(m_customGradient, TQT_SIGNAL(clicked()), autogradient, TQT_SLOT(show())); + + TQVBoxLayout *mainLayout = new TQVBoxLayout(this, 2, -1, "main tqlayout"); + + mainLayout->addWidget(m_lbName); + mainLayout->addWidget(chooserWidget(), 10); + mainLayout->addWidget(m_customGradient, 10); + +} + +KisGradientChooser::~KisGradientChooser() +{ +} + +void KisGradientChooser::update(KoIconItem *item) +{ + KisIconItem *kisItem = static_cast<KisIconItem *>(item); + + if (item) { + KisGradient *gradient = static_cast<KisGradient *>(kisItem->resource()); + + m_lbName->setText(gradient->name()); + } +} + + +#include "kis_gradient_chooser.moc" + diff --git a/chalk/ui/kis_gradient_chooser.h b/chalk/ui/kis_gradient_chooser.h new file mode 100644 index 00000000..fc154f3c --- /dev/null +++ b/chalk/ui/kis_gradient_chooser.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2004 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_GRADIENT_CHOOSER_H_ +#define KIS_GRADIENT_CHOOSER_H_ + +#include <kdialogbase.h> + +#include "kis_itemchooser.h" + +class TQLabel; +class TQPushButton; +class KisView; + +class KisCustomGradientDialog : public KDialogBase { + + Q_OBJECT + TQ_OBJECT + +public: + + KisCustomGradientDialog(KisView * view, TQWidget * tqparent, const char *name); + +private: + + KisAutogradient * m_page; + +}; + +class KisGradientChooser : public KisItemChooser { + typedef KisItemChooser super; + Q_OBJECT + TQ_OBJECT + +public: + // XXX: On library redesign, remove m_view parameter here, it's just a temporary hack for the autogradient dialog! + KisGradientChooser(KisView * view, TQWidget *tqparent = 0, const char *name = 0); + virtual ~KisGradientChooser(); + +protected: + virtual void update(KoIconItem *item); + +private: + TQLabel *m_lbName; + TQPushButton * m_customGradient; +}; + +#endif // KIS_GRADIENT_CHOOSER_H_ + diff --git a/chalk/ui/kis_gradient_slider_widget.cc b/chalk/ui/kis_gradient_slider_widget.cc new file mode 100644 index 00000000..3777a214 --- /dev/null +++ b/chalk/ui/kis_gradient_slider_widget.cc @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2004 Cyrille Berger <cberger@cberger.net> + * 2004 Sven Langkamp <longamp@reallygood.de> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_gradient_slider_widget.h" + +#include <tqpainter.h> + +#include <kdebug.h> +#include <kpopupmenu.h> +#include <klocale.h> + +#include "kis_autogradient_resource.h" + +#define MARGIN 5 +#define HANDLE_SIZE 10 + +KisGradientSliderWidget::KisGradientSliderWidget(TQWidget *tqparent, const char* name, WFlags f ) + : TQWidget( tqparent, name, f), + m_currentSegment(0), + m_selectedSegment(0), + m_drag(0) +{ + setMinimumHeight(30); + + m_segmentMenu = new KPopupMenu(); + m_segmentMenu->insertItem(i18n("Split Segment"), SPLIT_SEGMENT); + m_segmentMenu->insertItem(i18n("Duplicate Segment"), DUPLICATE_SEGMENT); + m_segmentMenu->insertItem(i18n("Mirror Segment"), MIRROR_SEGMENT); + m_segmentMenu->insertItem(i18n("Remove Segment"), REMOVE_SEGMENT); + connect( m_segmentMenu, TQT_SIGNAL( activated(int) ), TQT_SLOT( slotMenuAction(int) ) ); +} + +void KisGradientSliderWidget::setGradientResource( KisAutogradientResource* agr) +{ + m_autogradientResource = agr; + m_selectedSegment = m_autogradientResource->segmentAt(0.0); + emit sigSelectedSegment( m_selectedSegment ); +} + +void KisGradientSliderWidget::paintEvent ( TQPaintEvent* pe ) +{ + TQWidget::paintEvent( pe ); + TQPixmap pixmap( width(), height() ); + pixmap.fill( tqcolorGroup().background() ); + TQPainter painter( &pixmap ); + painter.setPen( TQt::black ); + painter.drawRect( MARGIN, MARGIN, width() - 2 * MARGIN, height()- 2 * MARGIN - HANDLE_SIZE ); + if(m_autogradientResource) + { + TQImage img = m_autogradientResource->generatePreview(width()- 2* MARGIN - 2, height()- 2* MARGIN - HANDLE_SIZE - 2); + TQPixmap pixmap(img.width(), img.height()); + if (!img.isNull()) { + m_pixmapIO.putImage(&pixmap, 0, 0, &img); + painter.drawPixmap( MARGIN + 1, MARGIN + 1, pixmap, 0, 0, pixmap.width(), pixmap.height()); + } + + painter.fillRect( MARGIN + 1, height()- MARGIN - HANDLE_SIZE, width() - 2 * MARGIN, HANDLE_SIZE, TQBrush( TQt::white ) ); + if( m_selectedSegment ) + { + TQRect selection( tqRound( m_selectedSegment->startOffset()*(double)(width()- 2 * MARGIN - 2) ) + 6, + height()- HANDLE_SIZE - MARGIN, + tqRound( ( m_selectedSegment->endOffset() - m_selectedSegment->startOffset() )*(double)(width()-12) ), + HANDLE_SIZE ); + painter.fillRect( selection, TQBrush( tqcolorGroup().highlight() ) ); + } + + TQPointArray triangle(3); + TQValueVector<double> handlePositions = m_autogradientResource->getHandlePositions(); + int position; + painter.setBrush( TQBrush( TQt::black) ); + for (uint i = 0; i < handlePositions.count(); i++) + { + position = tqRound( handlePositions[i] * (double)( width()-12) ) + 6; + triangle[0] = TQPoint(position, height() - HANDLE_SIZE - MARGIN ); + triangle[1] = TQPoint(position + (HANDLE_SIZE / 2 - 1), height() - MARGIN ); + triangle[2] = TQPoint(position - (HANDLE_SIZE / 2 - 1), height() - MARGIN ); + painter.drawPolygon(triangle); + } + painter.setBrush( TQBrush( TQt::white ) ); + TQValueVector<double> middleHandlePositions = m_autogradientResource->getMiddleHandlePositions(); + for (uint i = 0; i < middleHandlePositions.count(); i++) + { + position = tqRound( middleHandlePositions[i] * (double)(width()-12) ) + 6; + triangle[0] = TQPoint(position, height()-HANDLE_SIZE - MARGIN); + triangle[1] = TQPoint(position + (HANDLE_SIZE / 2 - 2), height() - MARGIN); + triangle[2] = TQPoint(position - (HANDLE_SIZE / 2 - 2), height() - MARGIN); + painter.drawPolygon(triangle); + } + } + bitBlt( this, 0, 0, &pixmap, 0, 0, pixmap.width(), pixmap.height(), TQt::CopyROP); +} + +void KisGradientSliderWidget::mousePressEvent( TQMouseEvent * e ) +{ + TQWidget::mousePressEvent( e ); + if( ( e->y() < MARGIN || e->y() > height() - MARGIN ) || ( e->x() < MARGIN || e->x() > width() - MARGIN ) || e-> button() != Qt::LeftButton ) + return; + double t = (double)(e->x() - MARGIN) / (double)(width() - 2 * MARGIN); + KisGradientSegment* segment = 0; + segment = m_autogradientResource->segmentAt(t); + if(segment != 0) + { + m_currentSegment = segment; + TQRect leftHandle( tqRound(m_currentSegment->startOffset() * (double)(width()-2*MARGIN-2)+ MARGIN - (HANDLE_SIZE/2 - 1 )), + height() - HANDLE_SIZE, + HANDLE_SIZE - 1, + HANDLE_SIZE); + TQRect middleHandle( tqRound(m_currentSegment->middleOffset() * (double)(width()-2*MARGIN-2)+ MARGIN - (HANDLE_SIZE/2 -2) ), + height() - HANDLE_SIZE - MARGIN, + HANDLE_SIZE - 1, + HANDLE_SIZE); + TQRect rightHandle( tqRound(m_currentSegment->endOffset() * (double)(width()-2*MARGIN-2)+ MARGIN - (HANDLE_SIZE/2 - 1 )), + height() - HANDLE_SIZE, + HANDLE_SIZE - 1, + HANDLE_SIZE); + // Change the activation order of the handles to avoid deadlocks + if( t > 0.5 ) + { + if( leftHandle.tqcontains( e->pos() ) ) + m_drag = LEFT_DRAG; + else if( middleHandle.tqcontains( e->pos() ) ) + m_drag = MIDDLE_DRAG; + else if( rightHandle.tqcontains( e->pos() ) ) + m_drag = RIGHT_DRAG; + } + else + { + if( rightHandle.tqcontains( e->pos() ) ) + m_drag = RIGHT_DRAG; + else if( middleHandle.tqcontains( e->pos() ) ) + m_drag = MIDDLE_DRAG; + else if( leftHandle.tqcontains( e->pos() ) ) + m_drag = LEFT_DRAG; + } + + if( m_drag == NO_DRAG ) + { + m_selectedSegment = m_currentSegment; + emit sigSelectedSegment( m_selectedSegment ); + } + } + tqrepaint(false); +} + +void KisGradientSliderWidget::mouseReleaseEvent ( TQMouseEvent * e ) +{ + TQWidget::mouseReleaseEvent( e ); + m_drag = NO_DRAG; +} + +void KisGradientSliderWidget::mouseMoveEvent( TQMouseEvent * e ) +{ + TQWidget::mouseMoveEvent( e ); + if( ( e->y() < MARGIN || e->y() > height() - MARGIN ) || ( e->x() < MARGIN || e->x() > width() - MARGIN ) ) + return; + double t = (double)(e->x() - MARGIN) / (double)(width() - 2 * MARGIN); + switch( m_drag ) + { + case RIGHT_DRAG: + m_autogradientResource->moveSegmentEndOffset( m_currentSegment, t ); + break; + case LEFT_DRAG: + m_autogradientResource->moveSegmentStartOffset( m_currentSegment, t ); + break; + case MIDDLE_DRAG: + m_autogradientResource->moveSegmentMiddleOffset( m_currentSegment, t ); + break; + } + + if ( m_drag != NO_DRAG) + emit sigChangedSegment( m_currentSegment ); + + tqrepaint(false); +} + +void KisGradientSliderWidget::contextMenuEvent( TQContextMenuEvent * e ) +{ + m_segmentMenu->setItemEnabled( REMOVE_SEGMENT, m_autogradientResource->removeSegmentPossible() ); + m_segmentMenu->popup( e->globalPos()); +} + +void KisGradientSliderWidget::slotMenuAction( int id ) +{ + switch( id ) + { + case SPLIT_SEGMENT: + m_autogradientResource->splitSegment( m_selectedSegment ); + break; + case DUPLICATE_SEGMENT: + m_autogradientResource->duplicateSegment( m_selectedSegment ); + break; + case MIRROR_SEGMENT: + m_autogradientResource->mirrorSegment( m_selectedSegment ); + break; + case REMOVE_SEGMENT: + m_selectedSegment = m_autogradientResource->removeSegment( m_selectedSegment ); + break; + } + emit sigSelectedSegment( m_selectedSegment ); + tqrepaint(false); +} + +#include "kis_gradient_slider_widget.moc" diff --git a/chalk/ui/kis_gradient_slider_widget.h b/chalk/ui/kis_gradient_slider_widget.h new file mode 100644 index 00000000..d15ac1c4 --- /dev/null +++ b/chalk/ui/kis_gradient_slider_widget.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2004 Cyrille Berger <cberger@cberger.net> + * 2004 Sven Langkamp <longamp@reallygood.de> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _KIS_WDG_GRADIENT_SLIDER_H_ +#define _KIS_WDG_GRADIENT_SLIDER_H_ + +#include <kpixmapio.h> +#include <tqwidget.h> + +class KPopupMenu; +class KisAutogradientResource; +class KisGradientSegment; + +class KisGradientSliderWidget : public TQWidget +{ + Q_OBJECT + TQ_OBJECT + +public: + KisGradientSliderWidget(TQWidget *tqparent = 0, const char* name = 0, WFlags f = 0); + +public: + virtual void paintEvent ( TQPaintEvent * ); + void setGradientResource( KisAutogradientResource* agr); + KisGradientSegment* selectedSegment() { return m_selectedSegment; }; + +signals: + void sigSelectedSegment(KisGradientSegment*); + void sigChangedSegment(KisGradientSegment*); + +protected: + virtual void mousePressEvent( TQMouseEvent * e ); + virtual void mouseReleaseEvent ( TQMouseEvent * e ); + virtual void mouseMoveEvent( TQMouseEvent * e ); + virtual void contextMenuEvent( TQContextMenuEvent * e ); + +private slots: + void slotMenuAction(int id); + +private: + + enum { + NO_DRAG, + LEFT_DRAG, + RIGHT_DRAG, + MIDDLE_DRAG + }; + + enum { + SPLIT_SEGMENT, + DUPLICATE_SEGMENT, + MIRROR_SEGMENT, + REMOVE_SEGMENT + }; + + KPixmapIO m_pixmapIO; + KisAutogradientResource* m_autogradientResource; + KisGradientSegment* m_currentSegment; + KisGradientSegment* m_selectedSegment; + KPopupMenu* m_segmentMenu; + int m_drag; +}; + +#endif diff --git a/chalk/ui/kis_grid_drawer.cpp b/chalk/ui/kis_grid_drawer.cpp new file mode 100644 index 00000000..f0d0e5f8 --- /dev/null +++ b/chalk/ui/kis_grid_drawer.cpp @@ -0,0 +1,223 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_grid_drawer.h" + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef HAVE_GL +#include <tqgl.h> +#endif + +#include "kis_config.h" +#include "kis_image.h" +#include "kis_perspective_grid.h" +#include "kis_perspective_grid_manager.h" + +Qt::PenStyle GridDrawer::gs2style(TQ_UINT32 s) +{ + switch(s) + { + case 1: + return Qt::DashLine; + case 2: + return Qt::DotLine; + case 3: + return Qt::DashDotLine; + case 4: + return Qt::DashDotDotLine; + default: + return Qt::SolidLine; + } +} + +void GridDrawer::drawPerspectiveGrid(KisImageSP image, const TQRect& /*wr*/, const KisSubPerspectiveGrid* grid) +{ + Q_UNUSED(image); + KisConfig cfg; + TQPen mainPen = TQPen ( cfg.getGridMainColor(), 1, gs2style( cfg.getGridMainStyle() ) ); + TQPen subdivisionPen = TQPen ( cfg.getGridSubdivisionColor(), 1, gs2style( cfg.getGridSubdivisionStyle() ) ); + setPen(subdivisionPen ); + // 1 -> top-left corner + // 2 -> top-right corner + // 3 -> bottom-right corner + // 4 -> bottom-left corner + // d12 line from top-left to top-right + // note that the notion of top-left is purely theorical + KisPerspectiveMath::LineEquation d12 = KisPerspectiveMath::computeLineEquation( grid->topLeft(), grid->topRight() ) ; + KisPoint v12 = KisPoint(*grid->topLeft() - *grid->topRight()); + v12.setX( v12.x() / grid->subdivisions()); v12.setY( v12.y() / grid->subdivisions() ); + KisPerspectiveMath::LineEquation d23 = KisPerspectiveMath::computeLineEquation( grid->topRight(), grid->bottomRight() ); + KisPoint v23 = KisPoint(*grid->topRight() - *grid->bottomRight()); + v23.setX( v23.x() / grid->subdivisions()); v23.setY( v23.y() / grid->subdivisions() ); + KisPerspectiveMath::LineEquation d34 = KisPerspectiveMath::computeLineEquation( grid->bottomRight(), grid->bottomLeft() ); + KisPerspectiveMath::LineEquation d41 = KisPerspectiveMath::computeLineEquation( grid->bottomLeft(), grid->topLeft() ); + + KisPoint horizVanishingPoint = KisPerspectiveMath::computeIntersection(d12,d34); + KisPoint vertVanishingPoint = KisPerspectiveMath::computeIntersection(d23,d41); + + for(uint i = 1; i < static_cast<uint>(grid->subdivisions()); i ++) + { + KisPoint pol1 = *grid->topRight() + i * v12; + KisPerspectiveMath::LineEquation d1 = KisPerspectiveMath::computeLineEquation( &pol1, &vertVanishingPoint ); + KisPoint pol1b = KisPerspectiveMath::computeIntersection(d1,d34); + drawLine( pol1.roundTQPoint(), pol1b.roundTQPoint() ); + + KisPoint pol2 = *grid->bottomRight() + i * v23; + KisPerspectiveMath::LineEquation d2 = KisPerspectiveMath::computeLineEquation( &pol2, &horizVanishingPoint ); + KisPoint pol2b = KisPerspectiveMath::computeIntersection(d2,d41); + drawLine( pol2.roundTQPoint(), pol2b.roundTQPoint() ); + } + setPen(mainPen); + drawLine( grid->topLeft(), grid->topRight() ); + drawLine( grid->topRight(), grid->bottomRight() ); + drawLine( grid->bottomRight(), grid->bottomLeft() ); + drawLine( grid->bottomLeft(), grid->topLeft() ); +} + +void GridDrawer::drawGrid(KisImageSP image, const TQRect& wr) +{ + KisConfig cfg; + + TQ_UINT32 offsetx = cfg.getGridOffsetX(); + TQ_UINT32 offsety = cfg.getGridOffsetY(); + TQ_UINT32 hspacing = cfg.getGridHSpacing(); + TQ_UINT32 vspacing = cfg.getGridVSpacing(); + TQ_UINT32 subdivision = cfg.getGridSubdivisions() - 1; + //double ihspsub = hspacing / (double)subdivision; + //double ivspsub = hspacing / (double)subdivision; + + TQ_INT32 imageWidth = image->width(); + TQ_INT32 imageHeight = image->height(); + + // Draw vertical line + TQPen mainPen = TQPen ( cfg.getGridMainColor(), 1, gs2style( cfg.getGridMainStyle() ) ); + TQPen subdivisionPen = TQPen ( cfg.getGridSubdivisionColor(), 1, gs2style( cfg.getGridSubdivisionStyle() ) ); + TQ_UINT32 i = 0; + for( TQ_INT32 x = offsetx; x <= wr.right(); x +=hspacing) + { + if( i == subdivision ) + { + setPen(mainPen); + i = 0; + } else { + setPen(subdivisionPen); + i++; + } + if( x >= wr.x() ) + { + // Always draw the full line otherwise the line stippling varies + // with the location of wr and we get glitchy patterns. + drawLine(x, 0, x, imageHeight); + } + } + // Draw horizontal line + i = 0; + for( TQ_INT32 y = offsety; y <= wr.bottom(); y +=vspacing) + { + if( i == subdivision ) + { + setPen(mainPen); + i = 0; + } else { + setPen(subdivisionPen); + i++; + } + if( y >= wr.y() ) + { + drawLine(0, y, imageWidth, y); + } + } +} + +OpenGLGridDrawer::OpenGLGridDrawer() +{ +#ifdef HAVE_GL + glPushAttrib(GL_ALL_ATTRIB_BITS); +#endif +} + +OpenGLGridDrawer::~OpenGLGridDrawer() +{ +#ifdef HAVE_GL + glPopAttrib(); +#endif +} + +void OpenGLGridDrawer::setPen(const TQPen& pen) +{ +#ifdef HAVE_GL + Qt::PenStyle penStyle = pen.style(); + + if (penStyle == TQt::SolidLine) { + glDisable(GL_LINE_STIPPLE); + } else { + GLushort lineStipple; + + switch (penStyle) { + case TQt::NoPen: + lineStipple = 0; + break; + default: + case TQt::SolidLine: + lineStipple = 0xffff; + break; + case TQt::DashLine: + lineStipple = 0x3fff; + break; + case TQt::DotLine: + lineStipple = 0x3333; + break; + case TQt::DashDotLine: + lineStipple = 0x33ff; + break; + case TQt::DashDotDotLine: + lineStipple = 0x333f; + break; + } + + glEnable(GL_LINE_STIPPLE); + glLineStipple(1, lineStipple); + } + + TQColor penColor = pen.color(); + + glColor3ub(penColor.red(), penColor.green(), penColor.blue()); +#else + Q_UNUSED(pen); +#endif +} + +void OpenGLGridDrawer::drawLine(TQ_INT32 x1, TQ_INT32 y1, TQ_INT32 x2, TQ_INT32 y2) +{ +#ifdef HAVE_GL + glBegin(GL_LINES); + glVertex2i(x1, y1); + glVertex2i(x2, y2); + glEnd(); +#else + Q_UNUSED(x1); + Q_UNUSED(y1); + Q_UNUSED(x2); + Q_UNUSED(y2); +#endif +} diff --git a/chalk/ui/kis_grid_drawer.h b/chalk/ui/kis_grid_drawer.h new file mode 100644 index 00000000..a37fd69e --- /dev/null +++ b/chalk/ui/kis_grid_drawer.h @@ -0,0 +1,71 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_GRID_DRAWER_H +#define KIS_GRID_DRAWER_H + +#include <math.h> + +#include <tqobject.h> +#include <tqpainter.h> + +#include "kis_types.h" +#include "kis_point.h" + +class KisSubPerspectiveGrid; + +class GridDrawer { + public: + GridDrawer() {} + virtual ~GridDrawer() {} + + public: + void drawGrid(KisImageSP image, const TQRect& wr); + void drawPerspectiveGrid(KisImageSP image, const TQRect& wr, const KisSubPerspectiveGrid* grid); + + virtual void setPen(const TQPen& pen) = 0; + virtual void drawLine(TQ_INT32 x1, TQ_INT32 y1, TQ_INT32 x2, TQ_INT32 y2) = 0; + inline void drawLine(const TQPoint& p1, const TQPoint& p2) { drawLine(p1.x(), p1.y(), p2.x(), p2.y() ); } + inline void drawLine(const KisPoint* p1, const KisPoint* p2) { drawLine( p1->roundTQPoint(), p2->roundTQPoint()); } + private: + Qt::PenStyle gs2style(TQ_UINT32 s); +}; + +class TQPainterGridDrawer : public GridDrawer { +public: + TQPainterGridDrawer(TQPainter *p) { m_painter = p; } + + virtual void setPen(const TQPen& pen) { m_painter->setPen(pen); } + virtual void drawLine(TQ_INT32 x1, TQ_INT32 y1, TQ_INT32 x2, TQ_INT32 y2) { m_painter->drawLine(x1, y1, x2, y2); } + +private: + TQPainter *m_painter; +}; + +class OpenGLGridDrawer : public GridDrawer { +public: + OpenGLGridDrawer(); + virtual ~OpenGLGridDrawer(); + + virtual void setPen(const TQPen& pen); + virtual void drawLine(TQ_INT32 x1, TQ_INT32 y1, TQ_INT32 x2, TQ_INT32 y2); +}; + +#endif diff --git a/chalk/ui/kis_grid_manager.cpp b/chalk/ui/kis_grid_manager.cpp new file mode 100644 index 00000000..53ee931c --- /dev/null +++ b/chalk/ui/kis_grid_manager.cpp @@ -0,0 +1,156 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_grid_manager.h" + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef HAVE_GL +#include <tqgl.h> +#endif + +#include <tqradiobutton.h> + +#include <kaction.h> +#include <kdialogbase.h> +#include <klocale.h> + + +#include "kis_config.h" +#include "kis_grid_drawer.h" +#include "kis_image.h" +#include "kis_view.h" + +KisGridManager::KisGridManager(KisView * tqparent) + : TQObject(tqparent), m_view(tqparent) +{ + +} + +KisGridManager::~KisGridManager() +{ + +} + +void KisGridManager::setup(KActionCollection * collection) +{ + m_toggleGrid = new KToggleAction(i18n("Show Grid"), "", this, TQT_SLOT(toggleGrid()), collection, "view_toggle_grid"); + m_toggleGrid->setCheckedState(KGuiItem(i18n("Hide Grid"))); + m_toggleGrid->setChecked(false); + + // Fast grid config + m_gridFastConfig1x1 = new KAction(i18n("1x1"), 0, "", this, TQT_SLOT(fastConfig1x1()), collection, "view_fast_grid_1x1"); + m_gridFastConfig2x2 = new KAction(i18n("2x2"), 0, "", this, TQT_SLOT(fastConfig2x2()), collection, "view_fast_grid_2x2"); + m_gridFastConfig5x5 = new KAction(i18n("5x5"), 0, "", this, TQT_SLOT(fastConfig5x5()), collection, "view_fast_grid_5x5"); + m_gridFastConfig10x10 = new KAction(i18n("10x10"), 0, "", this, TQT_SLOT(fastConfig10x10()), collection, "view_fast_grid_10x10"); + m_gridFastConfig20x20 = new KAction(i18n("20x20"), 0, "", this, TQT_SLOT(fastConfig20x20()), collection, "view_fast_grid_20x20"); + m_gridFastConfig40x40 = new KAction(i18n("40x40"), 0, "", this, TQT_SLOT(fastConfig40x40()), collection, "view_fast_grid_40x40"); +} + +void KisGridManager::updateGUI() +{ + +} + +void KisGridManager::toggleGrid() +{ + m_view->updateCanvas(); +} + +void KisGridManager::fastConfig1x1() +{ + KisConfig cfg; + cfg.setGridHSpacing(1); + cfg.setGridVSpacing(1); + m_view->updateCanvas(); +} + +void KisGridManager::fastConfig2x2() +{ + KisConfig cfg; + cfg.setGridHSpacing(2); + cfg.setGridVSpacing(2); + m_view->updateCanvas(); +} + +void KisGridManager::fastConfig5x5() +{ + KisConfig cfg; + cfg.setGridHSpacing(5); + cfg.setGridVSpacing(5); + m_view->updateCanvas(); +} + +void KisGridManager::fastConfig10x10() +{ + KisConfig cfg; + cfg.setGridHSpacing(10); + cfg.setGridVSpacing(10); + m_view->updateCanvas(); +} + +void KisGridManager::fastConfig20x20() +{ + KisConfig cfg; + cfg.setGridHSpacing(20); + cfg.setGridVSpacing(20); + m_view->updateCanvas(); +} + +void KisGridManager::fastConfig40x40() +{ + KisConfig cfg; + cfg.setGridHSpacing(40); + cfg.setGridVSpacing(40); + m_view->updateCanvas(); +} + +void KisGridManager::drawGrid(TQRect wr, TQPainter *p, bool openGL) +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + + if (image) { + if (m_toggleGrid->isChecked()) + { + GridDrawer *gridDrawer = 0; + + if (openGL) { + gridDrawer = new OpenGLGridDrawer(); + } else { + Q_ASSERT(p); + + if (p) { + gridDrawer = new TQPainterGridDrawer(p); + } + } + + Q_ASSERT(gridDrawer != 0); + + if (gridDrawer) { + gridDrawer->drawGrid(image, wr); + delete gridDrawer; + } + } + } +} + +#include "kis_grid_manager.moc" diff --git a/chalk/ui/kis_grid_manager.h b/chalk/ui/kis_grid_manager.h new file mode 100644 index 00000000..f4708ef0 --- /dev/null +++ b/chalk/ui/kis_grid_manager.h @@ -0,0 +1,65 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_GRID_MANAGER_H +#define KIS_GRID_MANAGER_H + +#include <tqobject.h> + +#include "kis_types.h" + +class KisView; +class KActionCollection; +class KToggleAction; +class KAction; + +class KisGridManager : public TQObject +{ + Q_OBJECT + TQ_OBJECT + public: + KisGridManager(KisView * tqparent); + ~KisGridManager(); + public: + void setup(KActionCollection * collection); + void drawGrid(TQRect wr, TQPainter *p, bool openGL = false); + public slots: + void updateGUI(); + private slots: + void toggleGrid(); + void fastConfig1x1(); + void fastConfig2x2(); + void fastConfig5x5(); + void fastConfig10x10(); + void fastConfig20x20(); + void fastConfig40x40(); + private: + KisView* m_view; + KToggleAction* m_toggleGrid; + KAction* m_gridConfig; + KAction* m_gridFastConfig1x1; + KAction* m_gridFastConfig2x2; + KAction* m_gridFastConfig5x5; + KAction* m_gridFastConfig10x10; + KAction* m_gridFastConfig20x20; + KAction* m_gridFastConfig40x40; +}; + +#endif diff --git a/chalk/ui/kis_histogram_view.cc b/chalk/ui/kis_histogram_view.cc new file mode 100644 index 00000000..cc4fe59c --- /dev/null +++ b/chalk/ui/kis_histogram_view.cc @@ -0,0 +1,354 @@ +/* + * Copyright (c) 2005 Bart Coppens <kde@bartcoppens.be> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <math.h> + +#include <tqpainter.h> +#include <tqpixmap.h> +#include <tqlabel.h> +#include <tqcombobox.h> +#include <tqbuttongroup.h> +#include <tqpushbutton.h> +#include <tqscrollbar.h> + +#include <kdebug.h> + +#include "kis_channelinfo.h" +#include "kis_histogram.h" +#include "kis_global.h" +#include "kis_types.h" +#include "kis_layer.h" +#include "kis_colorspace.h" +#include "kis_histogram_view.h" +#include "kis_basic_histogram_producers.h" +#include "kis_paint_device.h" + +KisHistogramView::KisHistogramView(TQWidget *tqparent, const char *name, WFlags f) + : TQLabel(tqparent, name, f) +{ + // This is needed until we can computationally scale it well. Until then, this is needed + // And when we have it, it won't hurt to have it around + setScaledContents(true); + setFrameShape(TQFrame::Box); // Draw a box around ourselves +} + +KisHistogramView::~KisHistogramView() +{ +} + +void KisHistogramView::setPaintDevice(KisPaintDeviceSP dev) +{ + m_cs = dev->colorSpace(); + + setChannels(); // Sets m_currentProducer to the first in the list + + if (!m_currentProducer) + return; + + m_from = m_currentProducer->viewFrom(); + m_width = m_currentProducer->viewWidth(); + + m_histogram = new KisHistogram(dev, m_currentProducer, LINEAR); + + updateHistogram(); +} + +void KisHistogramView::setHistogram(KisHistogramSP histogram) +{ + m_cs = 0; + m_histogram = histogram; + m_currentProducer = m_histogram->producer(); + m_from = m_currentProducer->viewFrom(); + m_width = m_currentProducer->viewWidth(); + + m_comboInfo.clear(); + m_channelStrings.clear(); + m_channels.clear(); + m_channelToOffset.clear(); + + addProducerChannels(m_currentProducer); + + // Set the currently viewed channel: + m_color = false; + m_channels.append(m_comboInfo.at(1).channel); + m_channelToOffset.append(0); + + updateHistogram(); +} + +void KisHistogramView::setView(double from, double size) +{ + m_from = from; + m_width = size; + if (m_from + m_width > 1.0) + m_from = 1.0 - m_width; + m_histogram->producer()->setView(m_from, m_width); + + m_histogram->updateHistogram(); + updateHistogram(); +} + +KisHistogramProducerSP KisHistogramView::currentProducer() +{ + return m_currentProducer; +} + +TQStringList KisHistogramView::channelStrings() +{ + return m_channelStrings; +} + +KisIDList KisHistogramView::listProducers() +{ + if (m_cs) + return KisHistogramProducerFactoryRegistry::instance()->listKeysCompatibleWith(m_cs); + return KisIDList(); +} + +void KisHistogramView::setCurrentChannels(const KisID& producerID, TQValueVector<KisChannelInfo *> channels) +{ + setCurrentChannels( + KisHistogramProducerFactoryRegistry::instance()->get(producerID)->generate(), + channels); +} + +void KisHistogramView::setCurrentChannels(KisHistogramProducerSP producer, TQValueVector<KisChannelInfo *> channels) +{ + m_currentProducer = producer; + m_currentProducer->setView(m_from, m_width); + m_histogram->setProducer(m_currentProducer); + m_histogram->updateHistogram(); + m_histogram->setChannel(0); // Set a default channel, just being nice + + m_channels.clear(); + m_channelToOffset.clear(); + + if (channels.count() == 0) { + updateHistogram(); + return; + } + + TQValueVector<KisChannelInfo *> producerChannels = m_currentProducer->channels(); + + for (uint i = 0; i < channels.count(); i++) { + // Also makes sure the channel is actually in the producer's list + for (uint j = 0; j < producerChannels.count(); j++) { + if (channels.at(i)->name() == producerChannels.at(j)->name()) { + m_channelToOffset.append(m_channels.count()); // The first we append maps to 0 + m_channels.append(channels.at(i)); + } + } + } + + updateHistogram(); +} + +bool KisHistogramView::hasColor() +{ + return m_color; +} + +void KisHistogramView::setColor(bool set) +{ + if (set != m_color) { + m_color = set; + updateHistogram(); + } +} + +void KisHistogramView::setActiveChannel(int channel) +{ + ComboboxInfo info = m_comboInfo.at(channel); + if (info.producer.data() != m_currentProducer.data()) { + m_currentProducer = info.producer; + m_currentProducer->setView(m_from, m_width); + m_histogram->setProducer(m_currentProducer); + m_histogram->updateHistogram(); + } + + m_channels.clear(); + m_channelToOffset.clear(); + + if (!m_currentProducer) { + updateHistogram(); + return; + } + + if (info.isProducer) { + m_color = true; + m_channels = m_currentProducer->channels(); + for (uint i = 0; i < m_channels.count(); i++) + m_channelToOffset.append(i); + m_histogram->setChannel(0); // Set a default channel, just being nice + } else { + m_color = false; + TQValueVector<KisChannelInfo *> channels = m_currentProducer->channels(); + for (uint i = 0; i < channels.count(); i++) { + KisChannelInfo* channel = channels.at(i); + if (channel->name() == info.channel->name()) { + m_channels.append(channel); + m_channelToOffset.append(i); + break; + } + } + } + + updateHistogram(); +} + +void KisHistogramView::setHistogramType(enumHistogramType type) +{ + m_histogram->setHistogramType(type); + updateHistogram(); +} + +void KisHistogramView::setChannels() +{ + m_comboInfo.clear(); + m_channelStrings.clear(); + m_channels.clear(); + m_channelToOffset.clear(); + + KisIDList list = KisHistogramProducerFactoryRegistry::instance()->listKeysCompatibleWith(m_cs); + + if (list.count() == 0) { + // XXX: No native histogram for this colorspace. Using converted RGB. We should have a warning + KisGenericRGBHistogramProducerFactory f; + addProducerChannels(f.generate()); + } else { + for (uint i = 0; i < list.count(); i++) { + KisID id(*(list.at(i))); + addProducerChannels( KisHistogramProducerFactoryRegistry::instance()->get(id)->generate() ); + } + } + + m_currentProducer = m_comboInfo.at(0).producer; + m_color = false; + // The currently displayed channel and its offset + m_channels.append(m_comboInfo.at(1).channel); + m_channelToOffset.append(0); +} + +void KisHistogramView::addProducerChannels(KisHistogramProducerSP producer) { + ComboboxInfo info; + info.isProducer = true; + info.producer = producer; + // channel not used for a producer + TQValueVector<KisChannelInfo *> channels = info.producer->channels(); + int count = channels.count(); + m_comboInfo.append(info); + m_channelStrings.append(producer->id() . name()); + for (int j = 0; j < count; j++) { + info.isProducer = false; + info.channel = channels.at(j); + m_comboInfo.append(info); + m_channelStrings.append(TQString(" ").append(info.channel->name())); + } +} + +void KisHistogramView::updateHistogram() +{ + TQ_UINT32 height = this->height(); + int selFrom, selTo; // from - to in bins + + if (!m_currentProducer) { // Something's very wrong: no producer for this colorspace to update histogram with! + return; + } + + TQ_INT32 bins = m_histogram->producer()->numberOfBins(); + m_pix = TQPixmap(bins, height); + m_pix.fill(); + TQPainter p(&m_pix); + p.setBrush(TQt::black); + + // Draw the box of the selection, if any + if (m_histogram->hasSelection()) { + double width = m_histogram->selectionTo() - m_histogram->selectionFrom(); + double factor = static_cast<double>(bins) / m_histogram->producer()->viewWidth(); + selFrom = static_cast<int>(m_histogram->selectionFrom() * factor); + selTo = selFrom + static_cast<int>(width * factor); + p.drawRect(selFrom, 0, selTo - selFrom, height); + } else { + // We don't want the drawing to think we're in a selected area + selFrom = -1; + selTo = 2; + } + + TQ_INT32 i = 0; + double highest = 0; + bool blackOnBlack = false; + + // First we iterate once, so that we have the overall maximum. This is a bit inefficient, + // but not too much since the histogram caches the calculations + for (uint chan = 0; chan < m_channels.count(); chan++) { + m_histogram->setChannel(m_channelToOffset.at(chan)); + if ((double)m_histogram->calculations().getHighest() > highest) + highest = (double)m_histogram->calculations().getHighest(); + } + + for (uint chan = 0; chan < m_channels.count(); chan++) { + TQColor color; + m_histogram->setChannel(m_channelToOffset.at(chan)); + + if (m_color) { + color = m_channels.at(chan)->color(); + p.setPen(color); + } else { + color = TQt::black; + } + blackOnBlack = (color == TQt::black); + + if (m_histogram->getHistogramType() == LINEAR) { + double factor = (double)height / highest; + for( i=0; i<bins; ++i ) { + // So that we get a good view even with a selection box with + // black colors on background of black selection + if (i >= selFrom && i < selTo && blackOnBlack) { + p.setPen(TQt::white); + } else { + p.setPen(color); + } + p.drawLine(i, height, i, height - int(m_histogram->getValue(i) * factor)); + } + } else { + double factor = (double)height / (double)log(highest); + for( i = 0; i < bins; ++i ) { + // Same as above + if (i >= selFrom && i < selTo && blackOnBlack) { + p.setPen(TQt::white); + } else { + p.setPen(color); + } + p.drawLine(i, height, i, + height - int(log((double)m_histogram->getValue(i)) * factor)); + } + } + } + + setPixmap(m_pix); +} + +void KisHistogramView::mousePressEvent(TQMouseEvent * e) { + if (e->button() == Qt::RightButton) + emit rightClicked(e->globalPos()); + else + TQLabel::mousePressEvent(e); +} + + +#include "kis_histogram_view.moc" diff --git a/chalk/ui/kis_histogram_view.h b/chalk/ui/kis_histogram_view.h new file mode 100644 index 00000000..6b4524a8 --- /dev/null +++ b/chalk/ui/kis_histogram_view.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2005 Bart Coppens <kde@bartcoppens.be> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _KIS_HISTOGRAM_VIEW_ +#define _KIS_HISTOGRAM_VIEW_ + +#include <tqlabel.h> +#include <tqpixmap.h> +#include <tqvaluevector.h> +#include <tqstringlist.h> + +#include "kis_types.h" +#include "kis_histogram_producer.h" +#include "kis_histogram.h" + +class KisChannelInfo; + +/** + * This class displays a histogram. It has a list of channels it can select. The easy + * way is to display channelStrings() to the user, and then use a setActiveChannel + * with the integer the same as the one the selected string in that stringlist has. + * If the selected one is a producer, the histogram will automatically display all its + * channels, and color them if that is possible. + * + * You can also set the channels manually, just don't forget that the displayed channels + * all need to belong to the same producer! If you set them manually, don't forget to set + * the (non)usage of color as well. + * + * You can either set this to use a specific layer, or use a specific histogram. With the latter, + * some functionality will disappear, like listProducers(). Setting a histogram will discard + * info on the layer, and setting a layer will discard info on the histogram. + **/ +class KisHistogramView : public TQLabel { + Q_OBJECT + TQ_OBJECT +public: + KisHistogramView(TQWidget *tqparent = 0, const char *name = 0, WFlags f = 0); + virtual ~KisHistogramView(); + + void setPaintDevice(KisPaintDeviceSP dev); + void setHistogram(KisHistogramSP histogram); + void setView(double from, double size); + KisHistogramProducerSP currentProducer(); + TQStringList channelStrings(); + /** Lists all producers currently available */ + KisIDList listProducers(); + /** Sets the currently displayed channels to channels of the producer with producerID as ID*/ + void setCurrentChannels(const KisID& producerID, TQValueVector<KisChannelInfo *> channels); + /** Be careful, producer will be modified */ + void setCurrentChannels(KisHistogramProducerSP producer, TQValueVector<KisChannelInfo *> channels); + bool hasColor(); + void setColor(bool set); + +public slots: + void setActiveChannel(int channel); + void setHistogramType(enumHistogramType type); + void updateHistogram(); + +signals: + void rightClicked(const TQPoint& pos); + +protected: + virtual void mousePressEvent(TQMouseEvent * e); + +private: + void setChannels(); + void addProducerChannels(KisHistogramProducerSP producer); + + typedef struct { + bool isProducer; + KisHistogramProducerSP producer; + KisChannelInfo * channel; + } ComboboxInfo; + + TQValueVector<ComboboxInfo> m_comboInfo; + TQPixmap m_pix; + KisHistogramSP m_histogram; + KisColorSpace* m_cs; + KisHistogramProducerSP m_currentProducer; + TQValueVector<KisChannelInfo *> m_channels; + // Maps the channels in m_channels to a real channel offset in the producer->channels() + TQValueVector<TQ_INT32> m_channelToOffset; + TQStringList m_channelStrings; + bool m_color; + double m_from; + double m_width; +}; + +#endif // _KIS_HISTOGRAM_VIEW_ diff --git a/chalk/ui/kis_icon_item.cc b/chalk/ui/kis_icon_item.cc new file mode 100644 index 00000000..339017fc --- /dev/null +++ b/chalk/ui/kis_icon_item.cc @@ -0,0 +1,116 @@ +/* + * Copyright (c) 1999 Matthias Elter <elter@kde.org> + * Copyright (c) 2003 Patrick Julien <freak@codepimps.org + * + * 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 2 of the License, 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.g + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <kdebug.h> + +#include "kis_resource.h" +#include "kis_global.h" +#include "kis_icon_item.h" + +#define THUMB_SIZE 30 + +KisIconItem::KisIconItem(KisResource *resource) +{ + m_resource = resource; + validPixmap = false; + validThumb = false; + updatePixmaps(); +} + +KisIconItem::~KisIconItem() +{ +} + +void KisIconItem::updatePixmaps() +{ + validPixmap = false; + validThumb = false; + + if (m_resource && m_resource->valid()) { + TQImage img = m_resource->img(); + + if (img.isNull()) { + m_resource->setValid(false); + m_resource = 0; + return; + } + + if (img.width() > THUMB_SIZE || img.height() > THUMB_SIZE) { + TQImage thumb = img; + TQ_INT32 xsize = THUMB_SIZE; + TQ_INT32 ysize = THUMB_SIZE; + TQ_INT32 picW = thumb.width(); + TQ_INT32 picH = thumb.height(); + + if (picW > picH) { + float yFactor = (float)((float)(float)picH / (float)picW); + + ysize = (TQ_INT32)(yFactor * (float)THUMB_SIZE); + + if (ysize > THUMB_SIZE) + ysize = THUMB_SIZE; + } else if (picW < picH) { + float xFactor = (float)((float)picW / (float)picH); + + xsize = (TQ_INT32)(xFactor * (float)THUMB_SIZE); + + if (xsize > THUMB_SIZE) + xsize = THUMB_SIZE; + } + + thumb = thumb.smoothScale(xsize, ysize); + + if (!thumb.isNull()) { + m_thumb = TQPixmap(thumb); + validThumb = !m_thumb.isNull(); + } + } + + img = img.convertDepth(32); + m_pixmap = TQPixmap(img); + validPixmap = true; + } +} + +TQPixmap& KisIconItem::pixmap() const +{ + return const_cast<TQPixmap&>(m_pixmap); +} + +TQPixmap& KisIconItem::thumbPixmap() const +{ + return const_cast<TQPixmap&>(m_thumb); +} + +KisResource *KisIconItem::resource() const +{ + return m_resource; +} + +int KisIconItem::compare(const KoIconItem *o) const +{ + const KisIconItem *other = dynamic_cast<const KisIconItem *>(o); + + if (other != 0) { + return m_resource->name().localeAwareCompare(other->m_resource->name()); + } else { + return 0; + } +} + diff --git a/chalk/ui/kis_icon_item.h b/chalk/ui/kis_icon_item.h new file mode 100644 index 00000000..9e8f1b09 --- /dev/null +++ b/chalk/ui/kis_icon_item.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 1999 Matthias Elter <elter@kde.org> + * Copyright (c) 2003 Patrick Julien <freak@codepimps.org + * + * 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 2 of the License, 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.g + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_ICON_ITEM_H_ +#define KIS_ICON_ITEM_H_ + +#include <koIconChooser.h> + +class KisResource; + +class KisIconItem : public KoIconItem { + +public: + KisIconItem(KisResource *resource); + virtual ~KisIconItem(); + + virtual TQPixmap& pixmap() const; + virtual TQPixmap& thumbPixmap() const; + + KisResource *resource() const; + + virtual int compare(const KoIconItem *other) const; + + void updatePixmaps(); + +private: + KisResource *m_resource; + TQPixmap m_pixmap; + TQPixmap m_thumb; +}; + +#endif // KIS_ICON_ITEM_H_ + diff --git a/chalk/ui/kis_iconwidget.cc b/chalk/ui/kis_iconwidget.cc new file mode 100644 index 00000000..3e9ce4f1 --- /dev/null +++ b/chalk/ui/kis_iconwidget.cc @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2000 Matthias Elter <elter@kde.org> + * Copyright (c) 2003 Patrick Julien <freak@codepimps.org> + * + * 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 2 of the License, 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.g + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <tqpainter.h> +#include <koIconChooser.h> +#include "kis_iconwidget.h" + +KisIconWidget::KisIconWidget(TQWidget *tqparent, const char *name) : super(tqparent, name) +{ + m_item = 0; +} + +void KisIconWidget::slotSetItem(KoIconItem& item) +{ + m_item = &item; + update(); +} + +void KisIconWidget::drawButtonLabel(TQPainter *p) +{ + if (m_item) { + const TQPixmap& pix = m_item->pixmap(); + TQ_INT32 x = 2; + TQ_INT32 y = 2; + TQ_INT32 pw = pix.width(); + TQ_INT32 ph = pix.height(); + TQ_INT32 cw = width(); + TQ_INT32 ch = height(); + TQ_INT32 itemWidth = 24; + TQ_INT32 itemHeight = 24; + + if (pw < itemWidth) + x = (cw - pw) / 2; + if (ph < itemHeight) + y = (cw - ph) / 2; + + if (!m_item->hasValidThumb() || (pw <= itemWidth && ph <= itemHeight)) { + p->drawPixmap(x, y, pix, 0, 0, itemWidth, itemHeight); + } else { + const TQPixmap& thumbpix = m_item->thumbPixmap(); + + x = 2; + y = 2; + pw = thumbpix.width(); + ph = thumbpix.height(); + cw = width(); + ch = height(); + + if (pw < itemWidth) + x = (cw - pw) / 2; + + if (ph < itemHeight) + y = (cw - ph) / 2; + + p->drawPixmap(x, y, thumbpix, 0, 0, itemWidth, itemHeight); + } + + p->setPen(gray); + p->drawRect(0, 0, cw + 1, ch + 1); + } +} + +#include "kis_iconwidget.moc" + diff --git a/chalk/ui/kis_iconwidget.h b/chalk/ui/kis_iconwidget.h new file mode 100644 index 00000000..d65cbcbd --- /dev/null +++ b/chalk/ui/kis_iconwidget.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2000 Matthias Elter <elter@kde.org> + * Copyright (c) 2003 Patrick Julien <freak@codepimps.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_ICONWIDGET_H_ +#define KIS_ICONWIDGET_H_ + +#include <tqtoolbutton.h> + +class KoIconItem; + +class KisIconWidget : public TQToolButton { + typedef TQToolButton super; + Q_OBJECT + TQ_OBJECT + +/** + * The icon widget is used in the control box where the current color and brush + * are shown. + */ +public: + KisIconWidget(TQWidget *tqparent = 0, const char *name = 0); + +public slots: + void slotSetItem(KoIconItem& item); + +protected: + virtual void drawButtonLabel(TQPainter *gc); + +private: + KoIconItem *m_item; +}; + +#endif // KIS_ICONWIDGET_H_ + diff --git a/chalk/ui/kis_import_catcher.cc b/chalk/ui/kis_import_catcher.cc new file mode 100644 index 00000000..b2d04cab --- /dev/null +++ b/chalk/ui/kis_import_catcher.cc @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2006 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include <kdebug.h> + +#include "kis_import_catcher.h" +#include "kis_types.h" + +#include "kis_view.h" +#include "kis_doc.h" +#include "kis_image.h" +#include "kis_layer.h" +#include "kis_group_layer.h" + +KisImportCatcher::KisImportCatcher(KURL url, KisImageSP image) + : TQObject() + , m_doc( new KisDoc() ) + , m_image( image ) + , m_url( url ) +{ + m_doc->openURL(url); + if ( !m_doc->isLoading() ) { + slotLoadingFinished(); + } + else { + connect(m_doc, TQT_SIGNAL(loadingFinished()), this, TQT_SLOT(slotLoadingFinished())); + } +} + +void KisImportCatcher::slotLoadingFinished() +{ + KisImageSP importedImage = m_doc->currentImage(); + + if (importedImage) { + KisLayerSP importedImageLayer = importedImage->rootLayer().data(); + + if (importedImageLayer != 0) { + + if (importedImageLayer->numLayers() == 2) { + // Don't import the root if this is not a layered image (1 group layer + // plus 1 other). + importedImageLayer = importedImageLayer->firstChild(); + importedImageLayer->tqparent()->removeLayer(importedImageLayer); + } + + importedImageLayer->setName(m_url.prettyURL()); + + KisGroupLayerSP tqparent = 0; + KisLayerSP currentActiveLayer = m_image->activeLayer(); + + if (currentActiveLayer) { + tqparent = currentActiveLayer->tqparent(); + } + + if (tqparent == 0) { + tqparent = m_image->rootLayer(); + } + + m_image->addLayer(importedImageLayer.data(), tqparent, currentActiveLayer); + } + } + m_doc->deleteLater(); + deleteLater(); +} + + diff --git a/chalk/ui/kis_import_catcher.h b/chalk/ui/kis_import_catcher.h new file mode 100644 index 00000000..6f6923e1 --- /dev/null +++ b/chalk/ui/kis_import_catcher.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2006 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_IMPORT_CATCHER_H_ +#define KIS_IMPORT_CATCHER_H_ + +#include <tqobject.h> + +#include <kurl.h> + +#include <kis_types.h> + +class KisView; +class KisDoc; + +/** + * This small helper class takes an url and an image; tries to import + * the image at the url and shove the layers of the imported image + * into the first image after loading is done. + * + * Caveat: this class calls "delete this", which means that you new + * it and then never touch it again. Thanks you very much. + */ +class KisImportCatcher : TQObject { + + Q_OBJECT + TQ_OBJECT + +public: + + KisImportCatcher(KURL url, KisImageSP image); + +public slots: + + void slotLoadingFinished(); + +private: + KisDoc * m_doc; + KisImage * m_image; + KURL m_url; +}; + +#endif diff --git a/chalk/ui/kis_input_device.cc b/chalk/ui/kis_input_device.cc new file mode 100644 index 00000000..0923c727 --- /dev/null +++ b/chalk/ui/kis_input_device.cc @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2006 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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.g + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_input_device.h" + +#define UNKNOWN_INPUT_DEVICE_ID -1 +#define FIRST_INPUT_DEVICE_ID 0 + +TQ_INT32 KisInputDevice::NextInputDeviceID = FIRST_INPUT_DEVICE_ID; + +KisInputDevice KisInputDevice::Mouse; +KisInputDevice KisInputDevice::Stylus; +KisInputDevice KisInputDevice::Eraser; +KisInputDevice KisInputDevice::Puck; +KisInputDevice KisInputDevice::Unknown(UNKNOWN_INPUT_DEVICE_ID); + +TQValueVector<KisInputDevice> KisInputDevice::InputDevices; + +KisInputDevice::KisInputDevice() +{ + m_id = UNKNOWN_INPUT_DEVICE_ID; +} + +KisInputDevice KisInputDevice::allocateNextDevice() +{ + KisInputDevice inputDevice(NextInputDeviceID); + NextInputDeviceID++; + InputDevices.append(inputDevice); + + return inputDevice; +} + +KisInputDevice KisInputDevice::allocateInputDevice() +{ + allocateDefaultDevicesIfNeeded(); + + return allocateNextDevice(); +} + +void KisInputDevice::allocateDefaultDevicesIfNeeded() +{ + if (NextInputDeviceID == FIRST_INPUT_DEVICE_ID) { + Mouse = allocateNextDevice(); + Stylus = allocateNextDevice(); + Eraser = allocateNextDevice(); + Puck = allocateNextDevice(); + } +} + +TQValueVector<KisInputDevice> KisInputDevice::inputDevices() +{ + allocateDefaultDevicesIfNeeded(); + + return InputDevices; +} + +KisInputDevice KisInputDevice::mouse() +{ + allocateDefaultDevicesIfNeeded(); + return Mouse; +} + +KisInputDevice KisInputDevice::stylus() +{ + allocateDefaultDevicesIfNeeded(); + return Stylus; +} + +KisInputDevice KisInputDevice::eraser() +{ + allocateDefaultDevicesIfNeeded(); + return Eraser; +} + +KisInputDevice KisInputDevice::puck() +{ + allocateDefaultDevicesIfNeeded(); + return Puck; +} + +KisInputDevice KisInputDevice::unknown() +{ + allocateDefaultDevicesIfNeeded(); + return Unknown; +} + diff --git a/chalk/ui/kis_input_device.h b/chalk/ui/kis_input_device.h new file mode 100644 index 00000000..d85d4e3f --- /dev/null +++ b/chalk/ui/kis_input_device.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2006 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_INPUT_DEVICE_H_ +#define KIS_INPUT_DEVICE_H_ + +#include <tqvaluevector.h> + +class KisInputDevice { +public: + KisInputDevice(); + + static KisInputDevice allocateInputDevice(); + static TQValueVector<KisInputDevice> inputDevices(); + + friend inline bool operator==(const KisInputDevice&, const KisInputDevice&); + friend inline bool operator!=(const KisInputDevice&, const KisInputDevice&); + + friend inline bool operator<(const KisInputDevice &, const KisInputDevice &); + friend inline bool operator>(const KisInputDevice &, const KisInputDevice &); + + static KisInputDevice mouse(); // Standard mouse + static KisInputDevice stylus(); // Wacom stylus via TQTabletEvent + static KisInputDevice eraser(); // Wacom eraser via TQTabletEvent + static KisInputDevice puck(); // Wacom puck via TQTabletEvent + static KisInputDevice unknown(); + +private: + KisInputDevice(TQ_INT32 id) : m_id(id) {} + + TQ_INT32 id() const { return m_id; } + + static void allocateDefaultDevicesIfNeeded(); + static KisInputDevice allocateNextDevice(); + +private: + TQ_INT32 m_id; + + static TQ_INT32 NextInputDeviceID; + static TQValueVector<KisInputDevice> InputDevices; + + static KisInputDevice Mouse; + static KisInputDevice Stylus; + static KisInputDevice Eraser; + static KisInputDevice Puck; + static KisInputDevice Unknown; +}; + +inline bool operator==(const KisInputDevice &a, const KisInputDevice &b) +{ + return a.id() == b.id(); +} + +inline bool operator!=(const KisInputDevice &a, const KisInputDevice &b) +{ + return a.id() != b.id(); +} + +inline bool operator<(const KisInputDevice &a, const KisInputDevice &b) +{ + return a.id() < b.id(); +} + + +inline bool operator>(const KisInputDevice &a, const KisInputDevice &b) +{ + return a.id() > b.id(); +} + +#endif // KIS_INPUT_DEVICE_H_ + diff --git a/chalk/ui/kis_int_spinbox.cc b/chalk/ui/kis_int_spinbox.cc new file mode 100644 index 00000000..8dc0e68d --- /dev/null +++ b/chalk/ui/kis_int_spinbox.cc @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2006 Boudewijn Rempt <boud@valdyas.org> + * Copyright (c) 2006 Casper Boemann <cbr@boemann.dk> + * + * Requires the TQt widget libraries, available at no cost at + * http://www.troll.no/ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif +#include <assert.h> +#include <math.h> +#include <algorithm> + +#include <tqtimer.h> +#include <tqapplication.h> +#include <tqsize.h> +#include <tqslider.h> +#include <tqstyle.h> +#include <tqlabel.h> +#include <tqpopupmenu.h> +#include <tqlineedit.h> +#include <tqlayout.h> +#include <tqvalidator.h> + +#include <knuminput.h> +#include <kglobal.h> +#include <klocale.h> +#include <kdebug.h> +#include <karrowbutton.h> + +#include "kdialog.h" +#include "knumvalidator.h" +#include "kis_int_spinbox.h" + +class KisIntSpinbox::KisIntSpinboxPrivate { +public: + + KIntSpinBox * m_numinput; + KisPopupSlider *m_slider; + KArrowButton *m_arrow; + int m_prevValue; + TQValidator *m_validator; + TQTimer m_timer; +}; + + +KisIntSpinbox::KisIntSpinbox(TQWidget *tqparent, const char *name) + : TQWidget(tqparent, name) +{ + init(0); +} + +KisIntSpinbox::KisIntSpinbox(const TQString & /*label*/, int val, TQWidget *tqparent, const char *name) + : TQWidget(tqparent, name) +{ + init(val); +} + +void KisIntSpinbox::init(int val) +{ + d = new KisIntSpinboxPrivate( ); + TQBoxLayout * l = new TQHBoxLayout( this ); + + l->insertStretch(0, 1); + d->m_numinput = new KIntSpinBox(0, 100, 1, val, 10, this, "KisIntSpinbox::KIntSpinBox"); + + d->m_numinput->tqsetSizePolicy(TQSizePolicy::MinimumExpanding, TQSizePolicy::Fixed); + d->m_numinput->setSuffix("%"); + l->addWidget( d->m_numinput ); + + d->m_slider = new KisPopupSlider(0, 100, 10, val, Qt::Horizontal, this); + d->m_slider->setFrameStyle(TQFrame::Panel|TQFrame::Raised); + + d->m_arrow = new KArrowButton(this, Qt::DownArrow); + d->m_arrow->setPopup(d->m_slider); + d->m_arrow->setMaximumHeight( fontMetrics().height() + 4); + d->m_arrow->setEnabled(true); // Why is the arrow still gray? + + l->addWidget( d->m_arrow ); + + d->m_prevValue = val; + setValue(val); + setFocusProxy(d->m_numinput); + tqlayout(); + + connect(d->m_numinput, TQT_SIGNAL(valueChanged(int)), TQT_SLOT(spinboxValueChanged(int))); + connect(d->m_slider, TQT_SIGNAL(valueChanged(int)), TQT_SLOT(sliderValueChanged(int))); + connect(d->m_slider, TQT_SIGNAL(aboutToShow()), TQT_SLOT(slotAboutToShow())); + connect(d->m_slider, TQT_SIGNAL(aboutToHide()), TQT_SLOT(slotAboutToHide())); + + connect(&(d->m_timer), TQT_SIGNAL(timeout()), this, TQT_SLOT(slotTimeout())); +} + +void KisIntSpinbox::spinboxValueChanged(int val) +{ + setValue(val); + d->m_timer.start(300, true); + +} + +void KisIntSpinbox::sliderValueChanged(int val) +{ + setValue(val); + emit valueChanged(val); + emit valueChanged(val, true); +} + +void KisIntSpinbox::setRange(int lower, int upper, int /*step*/) +{ + upper = kMax(upper, lower); + lower = kMin(upper, lower); + d->m_slider->setRange(lower, upper); + + tqlayout(); +} + +void KisIntSpinbox::setMinValue(int min) +{ + setRange(min, maxValue(), d->m_slider->lineStep()); +} + +int KisIntSpinbox::minValue() const +{ + return d->m_slider->minValue(); +} + +void KisIntSpinbox::setMaxValue(int max) +{ + setRange(minValue(), max, d->m_slider->lineStep()); +} + +int KisIntSpinbox::maxValue() const +{ + return d->m_slider->maxValue(); +} + +KisIntSpinbox::~KisIntSpinbox() +{ + delete d; +} + +void KisIntSpinbox::setValue(int val) +{ + d->m_slider->blockSignals(true); + d->m_slider->setValue(val); + d->m_slider->blockSignals(false); + + d->m_numinput->blockSignals(true); + d->m_numinput->setValue(val); + d->m_numinput->blockSignals(false); +} + +int KisIntSpinbox::value() const +{ + return d->m_numinput->value(); // From the numinput: that one isn't in steps of ten +} + +void KisIntSpinbox::setLabel(const TQString & /*label*/) +{ +} + +void KisIntSpinbox::slotAboutToShow() +{ + d->m_prevValue = value(); +} + +void KisIntSpinbox::slotAboutToHide() +{ + if( d->m_prevValue != value() ) + { + emit finishedChanging( d->m_prevValue, value() ); + d->m_prevValue = value(); + } +} + +void KisIntSpinbox::slotTimeout() +{ + emit valueChanged(value()); + emit valueChanged(value(), true); +} +#include "kis_int_spinbox.moc" diff --git a/chalk/ui/kis_int_spinbox.h b/chalk/ui/kis_int_spinbox.h new file mode 100644 index 00000000..a5c4602e --- /dev/null +++ b/chalk/ui/kis_int_spinbox.h @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2006 Boudewijn Rempt <boud@valdyas.org> + * Copyright (c) 2006 Casper Boemann <cbr@boemann.dk> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#ifndef KIS_INT_SPINBOX_H_ +#define KIS_INT_SPINBOX_H_ + +#include <tqwidget.h> +#include <tqspinbox.h> +#include <tqslider.h> +#include <tqpopupmenu.h> + +#include <knumvalidator.h> + +class TQLabel; +class TQLineEdit; +class TQLayout; +class TQValidator; + +class KisPopupSlider : public TQPopupMenu { + Q_OBJECT + TQ_OBJECT + +public: + + KisPopupSlider(int minValue, int maxValue, int pageStep, int value, Qt::Orientation orientation, TQWidget * tqparent, const char * name = 0) + : TQPopupMenu(tqparent, name) + { + m_slider = new TQSlider(minValue, maxValue, pageStep, value, orientation, this, name); + //m_slider->setTracking(false); + insertItem(m_slider); + connect(m_slider, TQT_SIGNAL(valueChanged(int)), TQT_SIGNAL(valueChanged(int))); + } + void setTickInterval(int i) { m_slider->setTickInterval(i); } + void setRange(int minValue, int maxValue) { m_slider->setRange(minValue, maxValue); } + void setValue(int val) { m_slider->setValue(val); } + void setTickmarks(TQSlider::TickSetting t) { m_slider->setTickmarks(t); } + int lineStep () const{ return m_slider->lineStep(); } + int minValue () const{ return m_slider->minValue(); } + int maxValue () const{ return m_slider->maxValue(); } + int value () const{ return m_slider->value(); } + TQSlider *m_slider; + +signals: + void valueChanged(int); + +}; + +/** + * @short An input widget for integer numbers, consisting of a spinbox and + * a dropdown slider. + * + * KisIntSpinbox combines a TQSpinBox and a dropdown TQSlider + * to make an easy to use control for setting some integer + * parameter. + * + * + */ +class KisIntSpinbox : public TQWidget +{ + + Q_OBJECT + TQ_OBJECT + TQ_PROPERTY( int value READ value WRITE setValue ) + TQ_PROPERTY( int minValue READ minValue WRITE setMinValue ) + TQ_PROPERTY( int maxValue READ maxValue WRITE setMaxValue ) + +public: + + /** + * Constructs an input control for integer values + * with base 10 and initial value 0. + * + * @param tqparent tqparent TQWidget + * @param name internal name for this widget + */ + KisIntSpinbox(TQWidget *tqparent=0, const char *name=0); + /** + * Constructor + * It constructs a TQSpinBox that allows the input of integer numbers + * in the range of -INT_MAX to +INT_MAX. + * To enforce the value being in a range, use setRange(). + * + * @param label the tabel (may contain &, and my be empty) + * @param value initial value for the control + * @param tqparent tqparent TQWidget + * @param name internal name for this widget + */ + KisIntSpinbox(const TQString & label, int value, TQWidget* tqparent=0, const char *name=0); + + /** + * Destructor + * + * + */ + virtual ~KisIntSpinbox(); + + /** + * @return the current value. + */ + int value() const; + + /** + * @param min minimum value + * @param max maximum value + * @param step step size for the TQSlider + */ + void setRange(int min, int max, int step=1); + /** + * Sets the minimum value. + */ + void setMinValue(int min); + /** + * @return the minimum value. + */ + int minValue() const; + /** + * Sets the maximum value. + */ + void setMaxValue(int max); + /** + * @return the maximum value. + */ + int maxValue() const; + + /** + * Sets the spacing of tickmarks for the slider. + * + * @param minor Minor tickmark separation. + * @param major Major tickmark separation. + */ + void setSteps(int minor, int major); + + void setLabel(const TQString & label); + +public slots: + /** + * Sets the value of the control. + */ + void setValue(int); + + + void spinboxValueChanged(int val); + void sliderValueChanged(int val); + + void slotTimeout(); + +signals: + + /** + * Emitted every time the value changes (by calling setValue() or + * by user interaction). + * @param value the new opacity + */ + void valueChanged(int value); + + /** + * Emitted every time the value changes (by calling setValue() or + * by user interaction). + * @param value the new opacity + * @param withSlider whether the value was set by dragging the slider + */ + void valueChanged(int value, bool withSlider); + + /** + * Emitted after the slider has been hidden, if the value was changed while it was shown. + * @param previous the value before the slider was shown + * @param value the value after the slider was hidden + */ + void finishedChanging(int previous, int value); + +private slots: + void slotAboutToShow(); + void slotAboutToHide(); + +private: + void init(int val); + +private: + + class KisIntSpinboxPrivate; + KisIntSpinboxPrivate *d; +}; + +#endif diff --git a/chalk/ui/kis_itemchooser.cc b/chalk/ui/kis_itemchooser.cc new file mode 100644 index 00000000..d418bd2f --- /dev/null +++ b/chalk/ui/kis_itemchooser.cc @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2002 Patrick Julien <freak@codepimps.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include <tqvbox.h> +#include <kinstance.h> +#include <klocale.h> +#include <kstandarddirs.h> +#include <koIconChooser.h> + +#include "kis_itemchooser.h" +#include "kis_global.h" +#include "kis_icon_item.h" + +KisItemChooser::KisItemChooser(TQWidget *tqparent, const char *name) : super(tqparent, name) +{ +/* m_frame = new TQVBox(this); + m_frame->setFrameStyle(TQFrame::Panel | TQFrame::Sunken);*/ + m_chooser = new KoIconChooser(TQSize(30,30), this, "icon_chooser", true); + TQObject::connect(m_chooser, TQT_SIGNAL(selected(KoIconItem*)), this, TQT_SLOT(slotItemSelected(KoIconItem*))); +} + +KisItemChooser::~KisItemChooser() +{ +} + +void KisItemChooser::setCurrent(KoIconItem *item) +{ + m_chooser->setCurrentItem(item); + update(item); +} + +void KisItemChooser::setCurrent(int index) +{ + setCurrent(m_chooser->itemAt(index)); +} + +KoIconItem* KisItemChooser::currentItem() +{ + return m_chooser->currentItem(); +} + +void KisItemChooser::slotItemSelected(KoIconItem *item) +{ + update(item); + emit selected(currentItem()); +} + +void KisItemChooser::addItem(KoIconItem *item) +{ + m_chooser->addItem(item); +} + +void KisItemChooser::addItems(const vKoIconItem& items) +{ + TQPtrListIterator<KoIconItem> itr(items); + + for (itr.toFirst(); itr.current(); ++itr) + m_chooser->addItem(itr.current()); +} + +TQWidget *KisItemChooser::chooserWidget() const +{ + return m_chooser; +} + +#include "kis_itemchooser.moc" + diff --git a/chalk/ui/kis_itemchooser.h b/chalk/ui/kis_itemchooser.h new file mode 100644 index 00000000..d29aa28d --- /dev/null +++ b/chalk/ui/kis_itemchooser.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2002 Patrick Julein <freak@codepimps.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_ITEM_CHOOSER_H_ +#define KIS_ITEM_CHOOSER_H_ + +#include <tqptrlist.h> +#include <tqwidget.h> + +class TQHBox; + +class KoIconChooser; +class KoIconItem; + +typedef TQPtrList<KoIconItem> vKoIconItem; + +class KisItemChooser : public TQWidget { + typedef TQWidget super; + Q_OBJECT + TQ_OBJECT + +public: + KisItemChooser(TQWidget *tqparent = 0, + const char *name = 0); + virtual ~KisItemChooser(); + + KoIconItem *currentItem(); + void setCurrent(KoIconItem *item); + void setCurrent(int index); + +public slots: + void addItem(KoIconItem *item); + void addItems(const vKoIconItem& items); + +signals: + void selected(KoIconItem *item); + +protected: + virtual void update(KoIconItem *item) = 0; + TQWidget *chooserWidget() const; + +private slots: + void slotItemSelected(KoIconItem *item); + +private: + TQHBox *m_frame; + KoIconChooser *m_chooser; +}; + +#endif // KIS_ITEM_CHOOSER_H_ + diff --git a/chalk/ui/kis_label_cursor_pos.cc b/chalk/ui/kis_label_cursor_pos.cc new file mode 100644 index 00000000..984df6dd --- /dev/null +++ b/chalk/ui/kis_label_cursor_pos.cc @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2003 Patrick Julien <freak@codepimps.org> + * + * 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 2 of the License, 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.g + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "kis_label_cursor_pos.h" +#include "kis_label_cursor_pos.moc" + +KisLabelCursorPos::KisLabelCursorPos(TQWidget *tqparent, const char *name, WFlags f) : super(tqparent, name, f) +{ + setText("0:0"); + m_doUpdates = true; + + //setMinimumSize( 200, tqparent->height() - 4); +} + +KisLabelCursorPos::~KisLabelCursorPos() +{ +} + +void KisLabelCursorPos::updatePos(TQ_INT32 xpos, TQ_INT32 ypos) +{ + if (m_doUpdates) { + TQString s; + + s.sprintf("%d:%d", xpos, ypos); + setText(s); + } +} + +void KisLabelCursorPos::enter() +{ + m_doUpdates = true; +} + +void KisLabelCursorPos::leave() +{ + m_doUpdates = false; + setText(TQString()); +} + diff --git a/chalk/ui/kis_label_cursor_pos.h b/chalk/ui/kis_label_cursor_pos.h new file mode 100644 index 00000000..392a0b68 --- /dev/null +++ b/chalk/ui/kis_label_cursor_pos.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2003 Patrick Julien <freak@codepimps.org> + * + * 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 2 of the License, 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.g + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_LABEL_CURSOR_POS_H_ +#define KIS_LABEL_CURSOR_POS_H_ + +#include <tqlabel.h> + +class KisLabelCursorPos : public TQLabel { + Q_OBJECT + TQ_OBJECT + typedef TQLabel super; + +public: + KisLabelCursorPos(TQWidget *tqparent, const char *name = 0, WFlags f = 0); + virtual ~KisLabelCursorPos(); + +public slots: + void updatePos(TQ_INT32 xpos, TQ_INT32 ypos); + void enter(); + void leave(); + +private: + bool m_doUpdates; + TQ_INT32 m_ypos; +}; + +#endif // KIS_LABEL_CURSOR_POS_H_ + diff --git a/chalk/ui/kis_label_progress.cc b/chalk/ui/kis_label_progress.cc new file mode 100644 index 00000000..c04452f4 --- /dev/null +++ b/chalk/ui/kis_label_progress.cc @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2002 Patrick Julien <freak@codepimps.org> + * 2004 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include <tqlayout.h> +#include <tqtooltip.h> +#include <tqtoolbutton.h> +#include <tqcursor.h> +#include <tqeventloop.h> + +#include <kdebug.h> +#include <kapplication.h> +#include <klocale.h> +#include <kprogress.h> +#include <kiconloader.h> + +#include "kis_progress_subject.h" +#include "kis_label_progress.h" +#include "kis_cursor.h" + +class EscapeButton : public TQToolButton { + +public: + + EscapeButton(TQWidget * tqparent, const char * name) : TQToolButton(tqparent, name) {}; + + void keyReleaseEvent(TQKeyEvent *e) + { + if (e->key()==TQt::Key_Escape) + emit clicked(); + } +}; + +KisLabelProgress::KisLabelProgress(TQWidget *tqparent, const char *name, WFlags f) : super(tqparent, name, f) +{ + m_subject = 0; + m_modal = false; + + TQHBoxLayout *box = new TQHBoxLayout(this); + box->setAutoAdd(true); + + TQIconSet cancelIconSet = SmallIconSet("stop"); + + m_cancelButton = new EscapeButton(this, "cancel_button"); + m_cancelButton->setIconSet(cancelIconSet); + TQToolTip::add(m_cancelButton, i18n("Cancel")); + connect(m_cancelButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(cancelPressed())); + + m_bar = new KProgress(100, this); +} + +KisLabelProgress::~KisLabelProgress() +{ +} + +void KisLabelProgress::setSubject(KisProgressSubject *subject, bool modal, bool canCancel) +{ + reset(); + + if (subject) { + m_subject = subject; + m_modal = modal; + + connect(subject, TQT_SIGNAL(notifyProgress(int)), this, TQT_SLOT(update(int))); + connect(subject, TQT_SIGNAL(notifyProgressStage(const TQString&, int)), this, TQT_SLOT(updateStage(const TQString&, int))); + connect(subject, TQT_SIGNAL(notifyProgressDone()), this, TQT_SLOT(done())); + connect(subject, TQT_SIGNAL(notifyProgressError()), this, TQT_SLOT(error())); + connect(subject, TQT_SIGNAL(destroyed()), this, TQT_SLOT(subjectDestroyed())); + + show(); + + if (canCancel) { + if (modal) { + kdDebug() << "grabbing 1\n"; + m_cancelButton->grabMouse(); + m_cancelButton->grabKeyboard(); + } + } + else { + m_cancelButton->hide(); + + if (modal) { + // Only visible widgets can grab. + kdDebug() << "grabbing 2\n"; + grabMouse(); + grabKeyboard(); + } + } + + if (modal) { + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + } + + m_bar->setValue(0); + } +} + +bool KisLabelProgress::event(TQEvent * e) +{ + + if (!e) return false; + + int type = e->type(); + + switch (type) { + case(KisProgress::ProgressEventBase + 1): + { + KisProgress::UpdateEvent * ue = dynamic_cast<KisProgress::UpdateEvent*>(e); + update(ue->m_percent); + break; + } + case(KisProgress::ProgressEventBase + 2): + { + KisProgress::UpdateStageEvent * use = dynamic_cast<KisProgress::UpdateStageEvent*>(e); + updateStage(use->m_stage, use->m_percent); + break; + } + case(KisProgress::ProgressEventBase + 3): + done(); + break; + case(KisProgress::ProgressEventBase + 4): + error(); + break; + case(KisProgress::ProgressEventBase + 5): + subjectDestroyed(); + break; + default: + return TQLabel::event(e); + }; + + return true; +} + +void KisLabelProgress::reset() +{ + if (m_subject) { + m_subject->disconnect(this); + m_subject = 0; + + if (m_modal) { + TQApplication::restoreOverrideCursor(); + } + + m_modal = false; + } + + releaseMouse(); + releaseKeyboard(); + m_cancelButton->releaseMouse(); + m_cancelButton->releaseKeyboard(); + hide(); +} + +void KisLabelProgress::update(int percent) +{ + m_bar->setValue(percent); + + KApplication *app = KApplication::kApplication(); + + app->processEvents(); + // The following is safer, but makes cancel impossible: + //TQApplication::eventLoop()->processEvents(TQEventLoop::ExcludeUserInput | + // TQEventLoop::ExcludeSocketNotifiers); +} + +void KisLabelProgress::updateStage(const TQString&, int percent) +{ + m_bar->setValue(percent); + + KApplication *app = KApplication::kApplication(); + Q_ASSERT(app); + + app->processEvents(); +} + +void KisLabelProgress::cancelPressed() +{ + if (m_subject) { + m_subject->cancel(); + reset(); + } +} + +void KisLabelProgress::subjectDestroyed() +{ + reset(); +} + +void KisLabelProgress::done() +{ + reset(); +} + +void KisLabelProgress::error() +{ + reset(); +} + +#include "kis_label_progress.moc" + diff --git a/chalk/ui/kis_label_progress.h b/chalk/ui/kis_label_progress.h new file mode 100644 index 00000000..a2c42fd9 --- /dev/null +++ b/chalk/ui/kis_label_progress.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2002 Patrick Julien <freak@codepimps.org> + * 2004 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_LABEL_PROGRESS_H_ +#define KIS_LABEL_PROGRESS_H_ + +#include <tqlabel.h> +#include <tqevent.h> + +#include "kis_progress_display_interface.h" + +class TQToolButton; +class KProgress; + +class KisLabelProgress : public TQLabel, public KisProgressDisplayInterface { + Q_OBJECT + TQ_OBJECT + typedef TQLabel super; + +public: + KisLabelProgress(TQWidget *tqparent, const char *name = 0, WFlags f = 0); + virtual ~KisLabelProgress(); + +public: + // Implements KisProgressDisplayInterface + void setSubject(KisProgressSubject *subject, bool modal, bool canCancel); + + // Overrides TQLabel::event() + bool event(TQEvent * ev); + +private slots: + virtual void update(int percent); + virtual void updateStage(const TQString& stage, int percent); + virtual void done(); + virtual void error(); + virtual void subjectDestroyed(); + +private slots: + void cancelPressed(); + +private: + void reset(); + + KisProgressSubject *m_subject; + KProgress *m_bar; + TQToolButton *m_cancelButton; + bool m_modal; +}; + +#endif // KIS_LABEL_PROGRESS_H_ + diff --git a/chalk/ui/kis_label_zoom.cc b/chalk/ui/kis_label_zoom.cc new file mode 100644 index 00000000..cd8620d6 --- /dev/null +++ b/chalk/ui/kis_label_zoom.cc @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_label_zoom.h" +#include "kis_label_zoom.moc" + diff --git a/chalk/ui/kis_label_zoom.h b/chalk/ui/kis_label_zoom.h new file mode 100644 index 00000000..e7fad08a --- /dev/null +++ b/chalk/ui/kis_label_zoom.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2002 Patrick Julien <freak@codepimps.org> + * + * 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 2 of the License, 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.g + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_LABEL_ZOOM_H_ +#define KIS_LABEL_ZOOM_H_ + +#include <tqlabel.h> + +class KisLabelZoom : public TQLabel { + Q_OBJECT + TQ_OBJECT + + KisLabelZoom( TQWidget *tqparent, const char *name = 0, WFlags f = 0 ) : + TQLabel( tqparent, name, f ) {} + virtual ~KisLabelZoom() {} + +}; + +#endif // KIS_LABEL_ZOOM_H_ + diff --git a/chalk/ui/kis_layerbox.cc b/chalk/ui/kis_layerbox.cc new file mode 100644 index 00000000..703fd3be --- /dev/null +++ b/chalk/ui/kis_layerbox.cc @@ -0,0 +1,675 @@ +/* + * kis_layerbox.cc - part of Chalk aka Krayon aka KimageShop + * + * Copyright (c) 2002 Patrick Julien <freak@codepimps.org> + * Copyright (C) 2006 Gábor Lehel <illissius@gmail.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <tqbutton.h> +#include <tqtoolbutton.h> +#include <tqbrush.h> +#include <tqfont.h> +#include <tqfontmetrics.h> +#include <tqhbox.h> +#include <tqlayout.h> +#include <tqpainter.h> +#include <tqpoint.h> +#include <tqrect.h> +#include <tqstring.h> +#include <tqstyle.h> +#include <tqtooltip.h> +#include <tqwidget.h> +#include <tqcombobox.h> +#include <tqcheckbox.h> + +#include <kdebug.h> +#include <kglobal.h> +#include <kpopupmenu.h> +#include <kmessagebox.h> +#include <kpushbutton.h> +#include <kiconloader.h> +#include <kicontheme.h> +#include <klocale.h> + +#include <KoPartSelectAction.h> + +#include "kis_layerlist.h" +#include "kis_cmb_composite.h" +#include "kis_int_spinbox.h" +#include "wdglayerbox.h" +#include "kis_colorspace.h" +#include "kis_paint_device.h" +#include "kis_layer.h" +#include "kis_group_layer.h" +#include "kis_image.h" + +#include "kis_populate_visitor.h" + +#include "kis_layerbox.h" + +KisLayerBox::KisLayerBox(KisCanvasSubject *subject, TQWidget *tqparent, const char *name) + : super(tqparent, name), m_image(0) +{ + TQVBoxLayout *vbox = new TQVBoxLayout(this); + vbox->setAutoAdd(true); + + m_lst = new WdgLayerBox(this); + setMinimumSize(m_lst->tqminimumSizeHint()); + + TQToolTip::add(m_lst->bnAdd, i18n("Create new layer")); + + TQToolTip::add(m_lst->bnDelete, i18n("Remove current layer")); + + TQToolTip::add(m_lst->bnRaise, i18n("Raise current layer")); + m_lst->bnRaise->setEnabled(false); + + m_lst->bnLower->setEnabled(false); + TQToolTip::add(m_lst->bnLower, i18n("Lower current layer")); + + TQToolTip::add(m_lst->bnProperties, i18n("Properties for layer")); + + KIconLoader il( "chalk" ); + + list()->setPreviewsShown(true); + + list()->setFoldersCanBeActive(true); + + list()->addProperty("visible", i18n("Visible"), loadPixmap("visible.png", il, KIcon::SizeSmallMedium), + loadPixmap("novisible.png", il, KIcon::SizeSmallMedium), true); + + list()->addProperty("locked", i18n("Locked"), loadPixmap("locked.png", il, KIcon::SizeSmallMedium), + loadPixmap("unlocked.png", il, KIcon::SizeSmallMedium)); + + + connect(list()->contextMenu(), TQT_SIGNAL(aboutToShow()), TQT_SLOT(slotAboutToShow())); + connect(list(), TQT_SIGNAL(activated(LayerItem*)), + TQT_SLOT(slotLayerActivated(LayerItem*))); + connect(list(), TQT_SIGNAL(displayNameChanged(LayerItem*, const TQString&)), + TQT_SLOT(slotLayerDisplayNameChanged(LayerItem*, const TQString&))); + connect(list(), TQT_SIGNAL(propertyChanged(LayerItem*, const TQString&, bool)), + TQT_SLOT(slotLayerPropertyChanged(LayerItem*, const TQString&, bool))); + connect(list(), TQT_SIGNAL(layerMoved(LayerItem*, LayerItem*, LayerItem*)), + TQT_SLOT(slotLayerMoved(LayerItem*, LayerItem*, LayerItem*))); + connect(list(), TQT_SIGNAL(requestNewLayer(LayerItem*, LayerItem*)), + TQT_SLOT(slotRequestNewLayer(LayerItem*, LayerItem*))); + connect(list(), TQT_SIGNAL(requestNewFolder(LayerItem*, LayerItem*)), + TQT_SLOT(slotRequestNewFolder(LayerItem*, LayerItem*))); + connect(list(), TQT_SIGNAL(requestNewAdjustmentLayer(LayerItem*, LayerItem*)), + TQT_SLOT(slotRequestNewAdjustmentLayer(LayerItem*, LayerItem*))); + connect(list(), TQT_SIGNAL(requestNewObjectLayer(LayerItem*, LayerItem*, const KoDocumentEntry&)), + TQT_SLOT(slotRequestNewObjectLayer(LayerItem*, LayerItem*, const KoDocumentEntry&))); + connect(list(), TQT_SIGNAL(requestRemoveLayer(LayerItem*)), + TQT_SLOT(slotRequestRemoveLayer(LayerItem*))); + connect(list(), TQT_SIGNAL(requestLayerProperties(LayerItem*)), + TQT_SLOT(slotRequestLayerProperties(LayerItem*))); + + m_newLayerMenu = new KPopupMenu(this); + m_lst->bnAdd->setPopup(m_newLayerMenu); + m_lst->bnAdd->setPopupDelay(1); + m_newLayerMenu->insertItem( SmallIconSet( "filenew" ), i18n( "&New Layer..." ), PAINT_LAYER ); + m_newLayerMenu->insertItem( SmallIconSet( "folder" ), i18n( "New &Group Layer..." ), GROUP_LAYER ); + m_newLayerMenu->insertItem( SmallIconSet( "tool_filter" ), i18n( "New &Adjustment Layer..." ), ADJUSTMENT_LAYER ); + m_partLayerAction = new KoPartSelectAction( i18n( "New &Object Layer" ), "gear", TQT_TQOBJECT(this) ); + m_partLayerAction->plug( m_newLayerMenu ); + connect(m_partLayerAction, TQT_SIGNAL(activated()), this, TQT_SLOT(slotAddMenuActivated())); + connect(m_newLayerMenu, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotAddMenuActivated(int))); + + + connect(m_lst->bnDelete, TQT_SIGNAL(clicked()), TQT_SLOT(slotRmClicked())); + connect(m_lst->bnRaise, TQT_SIGNAL(clicked()), TQT_SLOT(slotRaiseClicked())); + connect(m_lst->bnLower, TQT_SIGNAL(clicked()), TQT_SLOT(slotLowerClicked())); + connect(m_lst->bnProperties, TQT_SIGNAL(clicked()), TQT_SLOT(slotPropertiesClicked())); + connect(m_lst->intOpacity, TQT_SIGNAL(valueChanged(int, bool)), TQT_SIGNAL(sigOpacityChanged(int, bool))); + connect(m_lst->intOpacity, TQT_SIGNAL(finishedChanging(int, int)), TQT_SIGNAL(sigOpacityFinishedChanging(int, int))); + connect(m_lst->cmbComposite, TQT_SIGNAL(activated(const KisCompositeOp&)), TQT_SIGNAL(sigItemComposite(const KisCompositeOp&))); + + Q_ASSERT(subject->document() != 0); + + if (subject->document()) { + connect(subject->document(), TQT_SIGNAL(sigCommandExecuted()), TQT_SLOT(updateThumbnails())); + } +} + +KisLayerBox::~KisLayerBox() +{ +} + +KisLayerList* KisLayerBox::list() const +{ + return m_lst->listLayers; +} + +void KisLayerBox::setImage(KisImageSP img) +{ + if (m_image == img) + return; + + if (m_image) + m_image->disconnect(this); + + m_image = img; + + if (img) + { + connect(img, TQT_SIGNAL(sigLayerActivated(KisLayerSP)), this, TQT_SLOT(slotLayerActivated(KisLayerSP))); + connect(img, TQT_SIGNAL(sigLayerAdded(KisLayerSP)), this, TQT_SLOT(slotLayerAdded(KisLayerSP))); + connect(img, TQT_SIGNAL(sigLayerRemoved(KisLayerSP, KisGroupLayerSP, KisLayerSP)), + this, TQT_SLOT(slotLayerRemoved(KisLayerSP, KisGroupLayerSP, KisLayerSP))); + connect(img, TQT_SIGNAL(sigLayerPropertiesChanged(KisLayerSP)), + this, TQT_SLOT(slotLayerPropertiesChanged(KisLayerSP))); + connect(img, TQT_SIGNAL(sigLayerMoved(KisLayerSP, KisGroupLayerSP, KisLayerSP)), + this, TQT_SLOT(slotLayerMoved(KisLayerSP, KisGroupLayerSP, KisLayerSP))); + connect(img, TQT_SIGNAL(sigLayersChanged(KisGroupLayerSP)), this, TQT_SLOT(slotLayersChanged(KisGroupLayerSP))); + connect(img, TQT_SIGNAL(sigLayerUpdated(KisLayerSP, TQRect)), this, TQT_SLOT(slotLayerUpdated(KisLayerSP, TQRect))); + slotLayersChanged(img->rootLayer()); + updateThumbnails(); + } + else + { + clear(); + } +} + +void KisLayerBox::slotLayerActivated(KisLayerSP layer) +{ + if (layer) + list()->setActiveLayer(layer->id()); + else + list()->setActiveLayer(-1); + updateUI(); +} + +void KisLayerBox::slotLayerAdded(KisLayerSP layer) +{ + if (layer.data() == m_image->rootLayer().data() || list()->layer(layer->id())) + return; + + vKisLayerSP layersAdded; + + if (layer->tqparent() == m_image->rootLayer()) + { + KisPopulateVisitor visitor(list()); + layer->accept(visitor); + layersAdded = visitor.layersAdded(); + } + else + { + KisPopulateVisitor visitor(static_cast<KisLayerItem*>(list()->layer(layer->tqparent()->id()))); + layer->accept(visitor); + layersAdded = visitor.layersAdded(); + } + + for (vKisLayerSP::iterator it = layersAdded.begin(); it != layersAdded.end(); ++it) { + markModified(*it); + } + updateUI(); +} + +void KisLayerBox::slotLayerRemoved(KisLayerSP layer, KisGroupLayerSP wasParent, KisLayerSP) +{ + list()->removeLayer(layer->id()); + m_modified.remove(layer->id()); + markModified(wasParent); + updateUI(); +} + +void KisLayerBox::slotLayerMoved(KisLayerSP layer, KisGroupLayerSP wasParent, KisLayerSP) +{ + int tqparentID = layer->tqparent()->id(); + if (layer->tqparent() == m_image->rootLayer()) + tqparentID = -1; + + int siblingID = -1; + if (layer->prevSibling()) + siblingID = layer->prevSibling()->id(); + + list()->moveLayer(layer->id(), tqparentID, siblingID); + + markModified(layer->tqparent()); + markModified(wasParent); + updateUI(); +} + +void KisLayerBox::slotLayerPropertiesChanged(KisLayerSP layer) +{ + if (KisLayerItem* item = dynamic_cast<KisLayerItem*>(list()->layer(layer->id()))) + { + Q_ASSERT(item->layer() == layer.data()); + item->sync(); + updateUI(); + markModified(layer); + } +} + +void KisLayerBox::slotLayersChanged(KisGroupLayerSP rootLayer) +{ + list()->clear(); + KisPopulateVisitor visitor(list()); + for (KisLayerSP layer = rootLayer->firstChild(); layer; layer = layer->nextSibling()) + layer->accept(visitor); + m_modified.clear(); + for (TQListViewItemIterator it(list()->lastItem()); *it; --it) + m_modified.append(static_cast<LayerItem*>(*it)->id()); + updateUI(); +} + +void KisLayerBox::slotLayerUpdated(KisLayerSP layer, TQRect) +{ + markModified(layer); +} + +void KisLayerBox::slotLayerActivated(LayerItem* item) +{ + if (item) + m_image->activate(m_image->findLayer(item->id())); + else + m_image->activate(0); + updateUI(); +} + +void KisLayerBox::slotLayerDisplayNameChanged(LayerItem* item, const TQString& displayName) +{ + if(KisLayerSP layer = m_image->findLayer(item->id())) + layer->setName(displayName); + updateUI(); +} + +void KisLayerBox::slotLayerPropertyChanged(LayerItem* item, const TQString& name, bool on) +{ + if (KisLayerSP layer = m_image->findLayer(item->id())) + { + if (name == "visible") + layer->setVisible(on); + else if (name == "locked") + layer->setLocked(on); + } +} + +void KisLayerBox::slotLayerMoved(LayerItem* item, LayerItem*, LayerItem*) +{ + KisLayerSP layer = m_image->findLayer(item->id()); + KisGroupLayerSP tqparent; + if( item->tqparent() ) + tqparent = dynamic_cast<KisGroupLayer*>(m_image->findLayer(item->tqparent()->id()).data()); + if( !tqparent ) + tqparent = m_image->rootLayer(); + KisLayerSP above = 0; + if (item->nextSibling()) + above = m_image->findLayer(item->nextSibling()->id()); + if (layer) + m_image->moveLayer(layer, tqparent.data(), above); + updateUI(); +} + +void KisLayerBox::slotRequestNewLayer(LayerItem* p, LayerItem* after) +{ + KisLayer* l = m_image->rootLayer().data(); + if (p) + l = m_image->findLayer(p->id()).data(); + KisGroupLayerSP tqparent = dynamic_cast<KisGroupLayer*>(l); + + KisLayerSP above = 0; + if (after && after->nextSibling()) + above = m_image->findLayer(after->nextSibling()->id()); + else if (after) + above = 0; + else if (p && p->firstChild()) + above = tqparent->firstChild(); + else if (!p && m_image->rootLayer()->childCount()) + above = m_image->rootLayer()->firstChild(); + emit sigRequestLayer(tqparent, above); +} + +void KisLayerBox::slotRequestNewFolder(LayerItem* p, LayerItem* after) +{ + KisLayer* l = m_image->rootLayer().data(); //FIXME I hate copy-pasting like this. + if (p) + l = m_image->findLayer(p->id()).data(); + KisGroupLayerSP tqparent = dynamic_cast<KisGroupLayer*>(l); + + KisLayerSP above = 0; + if (after && after->nextSibling()) + above = m_image->findLayer(after->nextSibling()->id()); + else if (after) + above = 0; + else if (p && p->firstChild()) + above = tqparent->firstChild(); + else if (!p && m_image->rootLayer()->childCount()) + above = m_image->rootLayer()->firstChild(); + emit sigRequestGroupLayer(tqparent, above); +} + +void KisLayerBox::slotRequestNewAdjustmentLayer(LayerItem* p, LayerItem* after) +{ + KisLayer* l = m_image->rootLayer().data(); //FIXME here too. + if (p) + l = m_image->findLayer(p->id()).data(); + KisGroupLayerSP tqparent = dynamic_cast<KisGroupLayer*>(l); + + KisLayerSP above = 0; + if (after && after->nextSibling()) + above = m_image->findLayer(after->nextSibling()->id()); + else if (after) + above = 0; + else if (p && p->firstChild()) + above = tqparent->firstChild(); + else if (!p && m_image->rootLayer()->childCount()) + above = m_image->rootLayer()->firstChild(); + emit sigRequestAdjustmentLayer(tqparent, above); +} + +void KisLayerBox::slotRequestNewObjectLayer(LayerItem* p, LayerItem* after, const KoDocumentEntry& entry) +{ + KisLayer* l = m_image->rootLayer().data(); //FIXME and here. + if (p) + l = m_image->findLayer(p->id()).data(); + KisGroupLayerSP tqparent = dynamic_cast<KisGroupLayer*>(l); + + KisLayerSP above = 0; + if (after && after->nextSibling()) + above = m_image->findLayer(after->nextSibling()->id()); + else if (after) + above = 0; + else if (p && p->firstChild()) + above = tqparent->firstChild(); + else if (!p && m_image->rootLayer()->childCount()) + above = m_image->rootLayer()->firstChild(); + emit sigRequestPartLayer(tqparent, above, entry); +} + +void KisLayerBox::slotRequestRemoveLayer(LayerItem* item) +{ + if (KisLayerSP layer = m_image->findLayer(item->id())) { + m_image->removeLayer(layer); + } + updateUI(); +} + +void KisLayerBox::slotRequestLayerProperties(LayerItem* item) +{ + if (KisLayerSP layer = m_image->findLayer(item->id())) + { + emit sigRequestLayerProperties(layer); + } +} + +void KisLayerBox::updateUI() +{ + m_lst->bnDelete->setEnabled(list()->activeLayer()); + m_lst->bnRaise->setEnabled(list()->activeLayer() && (list()->activeLayer()->prevSibling() || list()->activeLayer()->tqparent())); + m_lst->bnLower->setEnabled(list()->activeLayer() && list()->activeLayer()->nextSibling()); + m_lst->intOpacity->setEnabled(list()->activeLayer()); + m_lst->cmbComposite->setEnabled(list()->activeLayer()); + if (m_image) + if (KisLayerSP active = m_image->activeLayer()) + { + if (m_image->activeDevice()) + slotSetColorSpace(m_image->activeDevice()->colorSpace()); + else + slotSetColorSpace(m_image->colorSpace()); + slotSetOpacity(int(float(active->opacity() * 100) / 255 + 0.5)); + slotSetCompositeOp(active->compositeOp()); + } +} + +void KisLayerBox::slotAboutToShow() +{ +} + +void KisLayerBox::slotSetCompositeOp(const KisCompositeOp& compositeOp) +{ + m_lst->cmbComposite->blockSignals(true); + m_lst->cmbComposite->setCurrentItem(compositeOp); + m_lst->cmbComposite->blockSignals(false); +} + +void KisLayerBox::slotSetColorSpace(const KisColorSpace * colorSpace) +{ + m_lst->cmbComposite->blockSignals(true); + m_lst->cmbComposite->setCompositeOpList(colorSpace->userVisiblecompositeOps()); + m_lst->cmbComposite->blockSignals(false); +} + +// range: 0-100 +void KisLayerBox::slotSetOpacity(int opacity) +{ + m_lst->intOpacity->blockSignals(true); + m_lst->intOpacity->setValue(opacity); + m_lst->intOpacity->blockSignals(false); +} + +void KisLayerBox::clear() +{ + list()->clear(); + updateUI(); +} + +void KisLayerBox::slotAddMenuActivated(int type) +{ + if(type == -1) + return; + + KisGroupLayerSP root = m_image->rootLayer(); + KisGroupLayerSP tqparent; + KisLayerSP above; + if (KisLayerSP active = m_image->activeLayer()) + { + tqparent = root; + above = active; + if (active->tqparent()) + tqparent = active->tqparent(); + } + else + { + tqparent = root; + above = m_image->rootLayer()->firstChild(); + } + + switch (type) + { + case PAINT_LAYER: + emit sigRequestLayer(tqparent, above); + break; + case GROUP_LAYER: + emit sigRequestGroupLayer(tqparent, above); + break; + case ADJUSTMENT_LAYER: + emit sigRequestAdjustmentLayer(tqparent, above); + break; + case OBJECT_LAYER: + default: //goddamned TQt doesn't emit activated for default-assigned IDs, so this does nothing + emit sigRequestPartLayer(tqparent, above, m_partLayerAction->documentEntry()); + } +} + +void KisLayerBox::slotRmClicked() +{ + TQValueList<int> l = list()->selectedLayerIDs(); + if (l.count() < 2 && list()->activeLayer() && !l.tqcontains(list()->activeLayer()->id())) + { + l.clear(); + l.append(list()->activeLayer()->id()); + } + + for (int i = 0, n = l.count(); i < n; ++i) + { + m_modified.remove(l[i]); + m_image->removeLayer(m_image->findLayer(l[i])); + } +} + +void KisLayerBox::slotRaiseClicked() +{ + TQValueList<int> l = list()->selectedLayerIDs(); + if (l.count() < 2 && list()->activeLayer() && !l.tqcontains(list()->activeLayer()->id())) + { + l.clear(); + l.append(list()->activeLayer()->id()); + } + + KisLayerSP layer = m_image->findLayer(l.first()); + if( l.count() == 1 && layer == layer->tqparent()->firstChild() && layer->tqparent() != m_image->rootLayer()) + { + if (KisGroupLayerSP grandtqparent = layer->tqparent()->tqparent()) + m_image->moveLayer(layer, grandtqparent, layer->tqparent().data()); + } + else + { + for (int i = 0, n = l.count(); i < n; ++i) + if (KisLayerSP li = m_image->findLayer(l[i])) + if (li->prevSibling()) + m_image->moveLayer(li, li->tqparent(), li->prevSibling()); + } + + if( !l.isEmpty() ) + list()->ensureItemVisible( list()->layer( l.first() ) ); +} + +void KisLayerBox::slotLowerClicked() +{ + TQValueList<LayerItem*> l = list()->selectedLayers(); + if (l.count() < 2 && list()->activeLayer() && !l.tqcontains(list()->activeLayer())) + { + l.clear(); + l.append(list()->activeLayer()); + } + + for (int i = l.count() - 1; i >= 0; --i) + if (LayerItem *layer = l[i]) + if (layer->nextSibling()) + list()->moveLayer(layer, layer->tqparent(), layer->nextSibling()); + + if( !l.isEmpty() ) + list()->ensureItemVisible( l.last() ); +} + +void KisLayerBox::slotPropertiesClicked() +{ + if (KisLayerSP active = m_image->activeLayer()) + emit sigRequestLayerProperties(active); +} + +void KisLayerBox::updateThumbnails() +{ + bool again = true; + while (m_modified.count() && again) + { + //again = false; + KisLayerItem* item = static_cast<KisLayerItem*>(list()->layer(m_modified.last())); + m_modified.pop_back(); + if (!item || !item->updatePreview()) + again = true; + } +} + +void KisLayerBox::setUpdatesAndSignalsEnabled(bool enable) +{ + setUpdatesEnabled(enable); + m_lst->intOpacity->setUpdatesEnabled(enable); + m_lst->cmbComposite->setUpdatesEnabled(enable); + + list()->blockSignals(!enable); + m_lst->intOpacity->blockSignals(!enable); + m_lst->cmbComposite->blockSignals(!enable); +} + + +TQPixmap KisLayerBox::loadPixmap(const TQString& filename, const KIconLoader& + il, int size) +{ + TQPixmap pixmap = il.loadIcon(filename, KIcon::NoGroup, size); + + if (pixmap.isNull()) + KMessageBox::error(0, i18n("Cannot tqfind %1").tqarg(filename), + i18n("Canvas")); + + return pixmap; +} + +void KisLayerBox::markModified(KisLayer* layer) +{ + if( !layer ) + return; + + TQValueList<int> v; + while (layer && layer != m_image->rootLayer().data()) + { + v.append(layer->id()); + layer = layer->tqparent(); + } + for (int i = v.count() - 1; i >= 0; --i) + if (!m_modified.tqcontains(v[i])) + m_modified.append(v[i]); +} + +void KisLayerBox::printChalkLayers() const +{ + static int indent = 0; + static KisLayer *root = 0; + if( !root ) + root = m_image->rootLayer(); + if( !root ) + return; + TQString s = root->name(); + if( dynamic_cast<KisGroupLayer*>( root ) ) + s = TQString("[%1]").tqarg( s ); + if( m_image->activeLayer().data() == root ) + s.prepend("*"); + kdDebug() << (TQString().fill(' ', indent) + s) << endl; + for (KisLayer* layer = root->firstChild(); layer; layer = layer->nextSibling()) + { + indent += 2; + root = layer; + printChalkLayers(); + indent -= 2; + root = layer->tqparent(); + } +} + +void KisLayerBox::printLayerboxLayers() const +{ + static int indent = 0; + static LayerItem *root = 0; + if( !root ) + { + for (LayerItem* layer = list()->firstChild(); layer; layer = layer->nextSibling()) + { + indent += 2; + root = layer; + printLayerboxLayers(); + indent -= 2; + root = layer->tqparent(); + } + return; + } + TQString s = root->displayName(); + if( root->isFolder() ) + s = TQString("[%1]").tqarg( s ); + if( list()->activeLayer() == root ) + s.prepend("*"); + kdDebug() << (TQString().fill(' ', indent) + s) << endl; + for (LayerItem* layer = root->firstChild(); layer; layer = layer->nextSibling()) + { + indent += 2; + root = layer; + printLayerboxLayers(); + indent -= 2; + root = layer->tqparent(); + } +} + +#include "kis_layerbox.moc" diff --git a/chalk/ui/kis_layerbox.h b/chalk/ui/kis_layerbox.h new file mode 100644 index 00000000..c9d14a88 --- /dev/null +++ b/chalk/ui/kis_layerbox.h @@ -0,0 +1,124 @@ +/* + * kis_layerbox.h - part of Chalk aka Krayon aka KimageShop + * + * Copyright (c) 2002 Patrick Julien <freak@codepimps.org> + * Copyright (C) 2006 Gábor Lehel <illissius@gmail.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_LAYERBOX_H +#define KIS_LAYERBOX_H + +#include <tqframe.h> +#include <kdebug.h> +#include <tqtimer.h> + +#include "kis_types.h" +#include "kis_colorspace.h" + +class WdgLayerBox; +class TQButton; +class TQPainter; +class TQWidget; +class KIconLoader; +class KPopupMenu; +class KoDocumentEntry; +class KisCompositeOp; +class KisLayerList; +class LayerItem; +class KisCanvasSubject; + +class KisLayerBox : public TQFrame { + typedef TQFrame super; + Q_OBJECT + TQ_OBJECT + +public: + KisLayerBox(KisCanvasSubject *subject, TQWidget *tqparent = 0, const char *name = 0); + virtual ~KisLayerBox(); + + void clear(); + void setUpdatesAndSignalsEnabled(bool enable); + void setImage(KisImageSP image); + +public slots: + // connect to KisImage signals + void slotLayerActivated(KisLayerSP layer); + void slotLayerAdded(KisLayerSP layer); + void slotLayerRemoved(KisLayerSP layer, KisGroupLayerSP wasParent, KisLayerSP wasAboveThis); + void slotLayerMoved(KisLayerSP layer, KisGroupLayerSP wasParent, KisLayerSP wasAboveThis); + void slotLayerPropertiesChanged(KisLayerSP layer); + void slotLayersChanged(KisGroupLayerSP rootLayer); + void slotLayerUpdated(KisLayerSP layer, TQRect rc); + + void slotSetCompositeOp(const KisCompositeOp& compositeOp); + void slotSetOpacity(int opacity); + void slotSetColorSpace(const KisColorSpace * colorSpace); + +signals: + void sigRequestLayer(KisGroupLayerSP tqparent, KisLayerSP above); + void sigRequestGroupLayer(KisGroupLayerSP tqparent, KisLayerSP above); + void sigRequestAdjustmentLayer(KisGroupLayerSP tqparent, KisLayerSP above); + void sigRequestPartLayer(KisGroupLayerSP tqparent, KisLayerSP above, const KoDocumentEntry& entry); + void sigRequestLayerProperties(KisLayerSP layer); + + void sigOpacityChanged(int opacity, bool withSlider); + void sigOpacityFinishedChanging(int previous, int opacity); + void sigItemComposite(const KisCompositeOp&); + +private: + enum LayerTypes { PAINT_LAYER, GROUP_LAYER, ADJUSTMENT_LAYER, OBJECT_LAYER }; + +private slots: + // connect to LayerList signals + void slotLayerActivated(LayerItem* layer); + void slotLayerDisplayNameChanged(LayerItem* layer, const TQString& displayName); + void slotLayerPropertyChanged(LayerItem* layer, const TQString& name, bool on); + void slotLayerMoved(LayerItem* layer, LayerItem* tqparent, LayerItem* after); + void slotRequestNewLayer(LayerItem* tqparent, LayerItem* after); + void slotRequestNewFolder(LayerItem* tqparent, LayerItem* after); + void slotRequestNewAdjustmentLayer(LayerItem* tqparent, LayerItem* after); + void slotRequestNewObjectLayer(LayerItem* tqparent, LayerItem* item, const KoDocumentEntry& entry); + void slotRequestRemoveLayer(LayerItem* layer); + void slotRequestLayerProperties(LayerItem* layer); + + void slotAboutToShow(); + void slotAddMenuActivated(int type = OBJECT_LAYER); + void slotRmClicked(); + void slotRaiseClicked(); + void slotLowerClicked(); + void slotPropertiesClicked(); + + void updateThumbnails(); + +private: + void updateUI(); + TQPixmap loadPixmap(const TQString& filename, const KIconLoader& il, int size); + KisLayerList* list() const; + void markModified(KisLayer *layer); + + KPopupMenu *m_newLayerMenu; + KoPartSelectAction *m_partLayerAction; + KisImageSP m_image; + TQValueList<int> m_modified; + WdgLayerBox *m_lst; + + void printChalkLayers() const; + void printLayerboxLayers() const; +}; + +#endif // KIS_LAYERBOX_H + diff --git a/chalk/ui/kis_layerlist.cc b/chalk/ui/kis_layerlist.cc new file mode 100644 index 00000000..64127d20 --- /dev/null +++ b/chalk/ui/kis_layerlist.cc @@ -0,0 +1,220 @@ +/* + Copyright (c) 2005 Gábor Lehel <illissius@gmail.com> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <kaboutdata.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kpopupmenu.h> +#include <KoPartSelectAction.h> +#include <tqimage.h> + +#include "kis_layer.h" +#include "kis_paint_layer.h" +#include "kis_part_layer.h" +#include "kis_adjustment_layer.h" +#include "kis_filter.h" +#include "kis_filter_configuration.h" +#include "kis_filter_registry.h" +#include "kis_layerlist.h" + + +KisLayerList::KisLayerList( TQWidget *tqparent, const char *name ) + : super( tqparent, name ) +{ + m_partLayerAction = new KoPartSelectAction( i18n( "New &Object Layer" ), "gear", TQT_TQOBJECT(this) ); +} + +static const int ADJUSTMENT_LAYER = 5384; //hack? + +void KisLayerList::constructMenu( LayerItem *layer ) +{ + super::constructMenu( layer ); + + contextMenu()->removeItem( MenuItems::NewLayer ); + contextMenu()->removeItem( MenuItems::NewFolder ); + contextMenu()->changeItem( MenuItems::RemoveLayer, i18n( "&Remove Layer" ) ); + + if( layer ) + { + static KPopupMenu submenu; + submenu.clear(); + submenu.insertItem( SmallIconSet( "file" ), i18n( "&Layer..." ), MenuItems::NewLayer ); + submenu.insertItem( SmallIconSet( "folder" ), i18n( "&Group Layer..." ), MenuItems::NewFolder ); + submenu.insertItem( SmallIconSet( "tool_filter" ), i18n( "&Adjustment Layer..." ), ADJUSTMENT_LAYER ); + m_partLayerAction->setText( i18n( "&Object Layer" ) ); + m_partLayerAction->plug( &submenu ); + + contextMenu()->insertItem( SmallIconSet( "filenew" ), i18n( "&New" ), &submenu ); + } + else + { + contextMenu()->insertItem( SmallIconSet( "filenew" ), i18n( "&New Layer..." ), MenuItems::NewLayer ); + contextMenu()->insertItem( SmallIconSet( "folder" ), i18n( "New &Group Layer..." ), MenuItems::NewFolder ); + contextMenu()->insertItem( SmallIconSet( "tool_filter" ), i18n( "New &Adjustment Layer..." ), ADJUSTMENT_LAYER ); + m_partLayerAction->setText( i18n( "New &Object Layer" ) ); + m_partLayerAction->plug( contextMenu() ); + } +} + +void KisLayerList::menuActivated( int id, LayerItem *layer ) +{ + const TQValueList<LayerItem*> selected = selectedLayers(); + LayerItem *tqparent = ( layer && layer->isFolder() ) ? layer : 0; + LayerItem *after = 0; + if( layer && !tqparent ) + { + tqparent = layer->tqparent(); + after = layer->prevSibling(); + } + switch( id ) + { + case MenuItems::NewLayer: + emit requestNewLayer( tqparent, after ); + emit requestNewLayer( tqparent ? tqparent->id() : -1, after ? after->id() : -1 ); + break; + case MenuItems::NewFolder: + emit requestNewFolder( tqparent, after ); + emit requestNewFolder( tqparent ? tqparent->id() : -1, after ? after->id() : -1 ); + break; + case ADJUSTMENT_LAYER: + emit requestNewAdjustmentLayer( tqparent, after ); + emit requestNewAdjustmentLayer( tqparent ? tqparent->id() : -1, after ? after->id() : -1 ); + break; + case MenuItems::RemoveLayer: + { + TQValueList<int> ids; + for( int i = 0, n = selected.count(); i < n; ++i ) + { + ids.append( selected[i]->id() ); + emit requestRemoveLayer( selected[i]->id() ); + } + emit requestRemoveLayers( ids ); + } + for( int i = 0, n = selected.count(); i < n; ++i ) + emit requestRemoveLayer( selected[i] ); + emit requestRemoveLayers( selected ); + break; + case MenuItems::LayerProperties: + if( layer ) + { + emit requestLayerProperties( layer ); + emit requestLayerProperties( layer->id() ); + } + break; + default: + if( id >= MenuItems::COUNT && layer ) + super::menuActivated( id, layer ); + else if( id != -1 ) //object layer was selected + { + emit requestNewObjectLayer( tqparent, after, m_partLayerAction->documentEntry() ); + emit requestNewObjectLayer( tqparent ? tqparent->id() : -1, after ? after->id() : -1, m_partLayerAction->documentEntry() ); + } + } +} + +KisLayerItem::KisLayerItem( LayerList* tqparent, KisLayer* layer ) + : super( layer->name(), + tqparent, + layer->prevSibling() ? tqparent->layer( layer->prevSibling()->id() ) : 0, + layer->id() ) + , m_layer( layer ) +{ + init(); +} + +KisLayerItem::KisLayerItem( LayerItem* tqparent, KisLayer* layer ) + : super( layer->name(), + tqparent, + layer->prevSibling() ? tqparent->listView()->layer( layer->prevSibling()->id() ) : 0, + layer->id() ) + , m_layer( layer ) +{ + init(); +} + +void KisLayerItem::init() +{ + setPreviewImage( &m_preview ); + sync(); +} + +KisLayer* KisLayerItem::layer() const +{ + return m_layer; +} + +void KisLayerItem::sync() +{ + setProperty( "visible", layer()->visible() ); + setProperty( "locked", layer()->locked() ); + setDisplayName( layer()->name() ); + update(); +} + +bool KisLayerItem::updatePreview() +{ + m_preview = m_layer->createThumbnail( height()*2, height()*2 ); + m_preview.setAlphaBuffer( true ); + previewChanged(); + return !m_preview.isNull(); +} + +TQString KisLayerItem::tooltip() const +{ + TQString text = super::tooltip(); + text = text.left( text.length() - 8 ); //HACK -- strip the </table> + TQString row = "<tr><td>%1</td><td>%2</td></tr>"; + text += row.tqarg( i18n( "Opacity:" ) ).tqarg( "%1%" ).tqarg( int( float( m_layer->opacity() * 100 ) / 255 + 0.5 ) ); + text += row.tqarg( i18n( "Composite mode:" ) ).tqarg( m_layer->compositeOp().id().name() ); + if( KisPaintLayer *player = dynamic_cast<KisPaintLayer*>( m_layer ) ) + { + text += row.tqarg( i18n( "Colorspace:" ) ).tqarg( player->paintDevice()->colorSpace()->id().name() ); + if( KisProfile *profile = player->paintDevice()->colorSpace()->getProfile() ) + text += row.tqarg( i18n( "Profile:" ) ).tqarg( profile->productName() ); + } + if( KisAdjustmentLayer *alayer = dynamic_cast<KisAdjustmentLayer*>( m_layer ) ) + text += row.tqarg( i18n( "Filter: " ) ).tqarg( KisFilterRegistry::instance()->get( alayer->filter()->name() )->id().name() ); + if( KisPartLayerImpl *player = dynamic_cast<KisPartLayerImpl*>( m_layer ) ) { + TQString type = player->docType(); + + if( type.isEmpty() ) { + type = player->childDoc()->document()->instance()->aboutData()->programName(); + } + + text += row.tqarg( i18n( "Document type: " ) ).tqarg( type ); + } + text += "</table>"; + + return text; +} + +TQImage KisLayerItem::tooltipPreview() const +{ + TQImage img = m_layer->createThumbnail( 400, 400 ); + if( img.isNull() ) + return img; //so TQt doesn't complain + img.setAlphaBuffer( true ); + const int size = kMin( 200, kMax( img.width(), img.height() ) ); + return img.smoothScale( size, size, TQ_ScaleMin ); +} + +//void KisLayerItem::paintCell( TQPainter *p, const TQColorGroup &cg, int column, int width, int align ); + +#include "kis_layerlist.moc" diff --git a/chalk/ui/kis_layerlist.h b/chalk/ui/kis_layerlist.h new file mode 100644 index 00000000..f0c587dd --- /dev/null +++ b/chalk/ui/kis_layerlist.h @@ -0,0 +1,80 @@ +/* + Copyright (c) 2005 Gábor Lehel <illissius@gmail.com> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KIS_LAYERLIST_H +#define KIS_LAYERLIST_H + +#include <tqimage.h> +#include "layerlist.h" + +class KoPartSelectAction; +class KoDocumentEntry; +class KisLayer; + +class KisLayerList: public LayerList +{ + Q_OBJECT + TQ_OBJECT + typedef LayerList super; + +signals: + void requestNewObjectLayer( LayerItem *tqparent, LayerItem *after, const KoDocumentEntry &entry ); + void requestNewObjectLayer( int tqparentID, int afterID, const KoDocumentEntry &entry ); + void requestNewAdjustmentLayer( LayerItem *tqparent, LayerItem *after ); + void requestNewAdjustmentLayer( int tqparentID, int afterID ); + +public: + KisLayerList( TQWidget *tqparent = 0, const char *name = 0 ); + + virtual void constructMenu( LayerItem *layer ); + virtual void menuActivated( int id, LayerItem *layer ); + + KoPartSelectAction *partLayerAction() const { return m_partLayerAction; } + +private: + KoPartSelectAction *m_partLayerAction; +}; + +class KisLayerItem: public LayerItem +{ + typedef LayerItem super; + +public: + KisLayerItem( LayerList* tqparent, KisLayer* layer ); + KisLayerItem( LayerItem* tqparent, KisLayer* layer ); + + KisLayer* layer() const; + + void sync(); + + /// returns whether any preview was retrieved + bool updatePreview(); + + virtual TQString tooltip() const; + virtual TQImage tooltipPreview() const; + + //virtual void paintCell( TQPainter *p, const TQColorGroup &cg, int column, int width, int align ); + +private: + void init(); + TQImage m_preview; + KisLayer *m_layer; +}; + +#endif diff --git a/chalk/ui/kis_load_visitor.h b/chalk/ui/kis_load_visitor.h new file mode 100644 index 00000000..1997d3bc --- /dev/null +++ b/chalk/ui/kis_load_visitor.h @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2002 Patrick Julien <freak@codepimps.org> + * Copyright (c) 2005 Casper Boemann <cbr@boemann.dk> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_LOAD_VISITOR_H_ +#define KIS_LOAD_VISITOR_H_ + +#include <tqrect.h> +#include "kis_types.h" +#include "kis_layer_visitor.h" +#include "kis_image.h" +#include "kis_selection.h" +#include "kis_layer.h" +#include "kis_paint_layer.h" +#include "kis_group_layer.h" +#include "kis_adjustment_layer.h" +#include "kis_filter_configuration.h" + +#include "kis_datamanager.h" + +class KisLoadVisitor : public KisLayerVisitor { +public: + KisLoadVisitor(KisImageSP img, KoStore *store, TQMap<KisLayerSP, TQString> &layerFilenames) : + KisLayerVisitor(), + m_layerFilenames(layerFilenames) + { + m_external = false; + m_img = img; + m_store = store; + } + +public: + void setExternalUri(TQString &uri) + { + m_external = true; + m_uri = uri; + } + + virtual bool visit(KisPaintLayer *layer) + { //connect(*layer->paintDevice(), TQT_SIGNAL(ioProgress(TQ_INT8)), m_img, TQT_SLOT(slotIOProgress(TQ_INT8))); + + TQString location = m_external ? TQString() : m_uri; + location += m_img->name() + "/layers/" + m_layerFilenames[layer]; + + // Layer data + if (m_store->open(location)) { + if (!layer->paintDevice()->read(m_store)) { + layer->paintDevice()->disconnect(); + m_store->close(); + //IODone(); + return false; + } + + m_store->close(); + } + + // icc profile + location = m_external ? TQString() : m_uri; + location += m_img->name() + "/layers/" + m_layerFilenames[layer] + ".icc"; + + if (m_store->hasFile(location)) { + TQByteArray data; + m_store->open(location); + data = m_store->read(m_store->size()); + m_store->close(); + // Create a colorspace with the embedded profile + KisColorSpace * cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(layer->paintDevice()->colorSpace()->id(), + new KisProfile(data)); + // replace the old colorspace + layer->paintDevice()->setData(layer->paintDevice()->dataManager(), cs); + TQRect rc = layer->paintDevice()->extent(); + kdDebug() << "After loading " << layer->name() << " extent is: " << rc.x() << ", " << rc.y() << ", " << rc.width() << ", " << rc.height() << endl; + layer->setDirty(rc); + kdDebug(DBG_AREA_FILE) << "Opened icc information, size is " << data.size() << endl; + } + + // tqmask + if (layer->hasMask()) { // We set this in KisDoc::loadPaintLayer + KisPaintDeviceSP tqmask = layer->getMask(); + location = m_external ? TQString() : m_uri; + location += m_img->name() + "/layers/" + m_layerFilenames[layer] + ".tqmask"; + + // Layer data + if (m_store->open(location)) { + if (!tqmask->read(m_store)) { + tqmask->disconnect(); + m_store->close(); + //IODone(); + return false; + } + + m_store->close(); + } + layer->setDirty(); // Update the entire layer + } + + return true; + + } + + virtual bool visit(KisGroupLayer *layer) + { + KisLoadVisitor visitor(m_img,m_store ,m_layerFilenames); + + if(m_external) + visitor.setExternalUri(m_uri); + + KisLayerSP child = layer->firstChild(); + + while(child) + { + child->accept(visitor); + child = child->nextSibling(); + } + + layer->setDirty(m_img->bounds()); + return true; + } + + virtual bool visit(KisPartLayer *) + { + return true; + } + + virtual bool visit(KisAdjustmentLayer* layer) + { + //connect(*layer->paintDevice(), TQT_SIGNAL(ioProgress(TQ_INT8)), m_img, TQT_SLOT(slotIOProgress(TQ_INT8))); + + // The selection -- if present. If not, we simply cannot open the dratted thing. + TQString location = m_external ? TQString() : m_uri; + location += m_img->name() + "/layers/" + m_layerFilenames[layer] + ".selection"; + if (m_store->hasFile(location)) { + m_store->open(location); + KisSelectionSP selection = new KisSelection(); + if (!selection->read(m_store)) { + selection->disconnect(); + m_store->close(); + } + else { + layer->setSelection( selection ); + } + m_store->close(); + } + + // filter configuration + location = m_external ? TQString() : m_uri; + location += m_img->name() + "/layers/" + m_layerFilenames[layer] + ".filterconfig"; + + if (m_store->hasFile(location) && layer->filter()) { + TQByteArray data; + m_store->open(location); + data = m_store->read(m_store->size()); + m_store->close(); + if (!data.isNull()) { + KisFilterConfiguration * kfc = layer->filter(); + kfc->fromXML(TQString(data)); + } + } + + return true; + + } + +private: + KisImageSP m_img; + KoStore *m_store; + bool m_external; + TQString m_uri; + TQMap<KisLayerSP, TQString> m_layerFilenames; +}; + +#endif // KIS_LOAD_VISITOR_H_ + diff --git a/chalk/ui/kis_matrix_widget.ui b/chalk/ui/kis_matrix_widget.ui new file mode 100644 index 00000000..b989df12 --- /dev/null +++ b/chalk/ui/kis_matrix_widget.ui @@ -0,0 +1,210 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>KisMatrixWidget</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>KisMatrixWidget</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>191</width> + <height>115</height> + </rect> + </property> + <property name="caption"> + <string>Matrix Widget</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQSpinBox" row="0" column="0"> + <property name="name"> + <cstring>m11</cstring> + </property> + <property name="minValue"> + <number>-99</number> + </property> + </widget> + <widget class="TQSpinBox" row="0" column="2"> + <property name="name"> + <cstring>m13</cstring> + </property> + <property name="minValue"> + <number>-99</number> + </property> + </widget> + <widget class="TQSpinBox" row="0" column="1"> + <property name="name"> + <cstring>m12</cstring> + </property> + <property name="minValue"> + <number>-99</number> + </property> + </widget> + <widget class="TQSpinBox" row="1" column="2"> + <property name="name"> + <cstring>m23</cstring> + </property> + <property name="minValue"> + <number>-99</number> + </property> + </widget> + <widget class="TQSpinBox" row="1" column="0"> + <property name="name"> + <cstring>m21</cstring> + </property> + <property name="minValue"> + <number>-99</number> + </property> + </widget> + <widget class="TQSpinBox" row="1" column="1"> + <property name="name"> + <cstring>m22</cstring> + </property> + <property name="minValue"> + <number>-99</number> + </property> + <property name="value"> + <number>1</number> + </property> + </widget> + <widget class="TQSpinBox" row="2" column="0"> + <property name="name"> + <cstring>m31</cstring> + </property> + <property name="minValue"> + <number>-99</number> + </property> + </widget> + <widget class="TQSpinBox" row="2" column="1"> + <property name="name"> + <cstring>m32</cstring> + </property> + <property name="minValue"> + <number>-99</number> + </property> + </widget> + <widget class="TQSpinBox" row="2" column="2"> + <property name="name"> + <cstring>m33</cstring> + </property> + <property name="minValue"> + <number>-99</number> + </property> + </widget> + <spacer row="3" column="1"> + <property name="name"> + <cstring>spacer4</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>20</width> + <height>41</height> + </size> + </property> + </spacer> + <spacer row="1" column="3"> + <property name="name"> + <cstring>spacer5</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>21</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> +</widget> +<connections> + <connection> + <sender>m11</sender> + <signal>valueChanged(int)</signal> + <receiver>KisMatrixWidget</receiver> + <slot>spinboxValueChanged()</slot> + </connection> + <connection> + <sender>m12</sender> + <signal>valueChanged(int)</signal> + <receiver>KisMatrixWidget</receiver> + <slot>spinboxValueChanged()</slot> + </connection> + <connection> + <sender>m13</sender> + <signal>valueChanged(int)</signal> + <receiver>KisMatrixWidget</receiver> + <slot>spinboxValueChanged()</slot> + </connection> + <connection> + <sender>m21</sender> + <signal>valueChanged(int)</signal> + <receiver>KisMatrixWidget</receiver> + <slot>spinboxValueChanged()</slot> + </connection> + <connection> + <sender>m22</sender> + <signal>valueChanged(int)</signal> + <receiver>KisMatrixWidget</receiver> + <slot>spinboxValueChanged()</slot> + </connection> + <connection> + <sender>m23</sender> + <signal>valueChanged(int)</signal> + <receiver>KisMatrixWidget</receiver> + <slot>spinboxValueChanged()</slot> + </connection> + <connection> + <sender>m31</sender> + <signal>valueChanged(int)</signal> + <receiver>KisMatrixWidget</receiver> + <slot>spinboxValueChanged()</slot> + </connection> + <connection> + <sender>m32</sender> + <signal>valueChanged(int)</signal> + <receiver>KisMatrixWidget</receiver> + <slot>spinboxValueChanged()</slot> + </connection> + <connection> + <sender>m33</sender> + <signal>valueChanged(int)</signal> + <receiver>KisMatrixWidget</receiver> + <slot>spinboxValueChanged()</slot> + </connection> +</connections> +<tabstops> + <tabstop>m11</tabstop> + <tabstop>m12</tabstop> + <tabstop>m13</tabstop> + <tabstop>m21</tabstop> + <tabstop>m22</tabstop> + <tabstop>m23</tabstop> + <tabstop>m31</tabstop> + <tabstop>m32</tabstop> + <tabstop>m33</tabstop> +</tabstops> +<includes> + <include location="local" impldecl="in implementation">kis_matrix_widget.ui.h</include> +</includes> +<Q_SIGNALS> + <signal>valueChanged()</signal> +</Q_SIGNALS> +<Q_SLOTS> + <slot access="private">spinboxValueChanged()</slot> +</Q_SLOTS> +<tqlayoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/chalk/ui/kis_matrix_widget.ui.h b/chalk/ui/kis_matrix_widget.ui.h new file mode 100644 index 00000000..f5217af5 --- /dev/null +++ b/chalk/ui/kis_matrix_widget.ui.h @@ -0,0 +1,17 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you want to add, delete, or rename functions or slots, use +** TQt Designer to update this file, preserving your code. +** +** You should not define a constructor or destructor in this file. +** Instead, write your code in functions called init() and destroy(). +** These will automatically be called by the form's constructor and +** destructor. +*****************************************************************************/ + + +void KisMatrixWidget::spinboxValueChanged() +{ + emit valueChanged(); +} diff --git a/chalk/ui/kis_move_event.h b/chalk/ui/kis_move_event.h new file mode 100644 index 00000000..8c99cd10 --- /dev/null +++ b/chalk/ui/kis_move_event.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2004 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_MOVE_EVENT_H_ +#define KIS_MOVE_EVENT_H_ + +#include "kis_event.h" + +class KisMoveEvent : public KisEvent { + typedef KisEvent super; +public: + KisMoveEvent() {} + KisMoveEvent(KisInputDevice device, const KisPoint& pos, const KisPoint& globalPos, double pressure, double xTilt, double yTilt, TQt::ButtonState state) : super(MoveEvent, device, pos, globalPos, pressure, xTilt, yTilt, state) {} +}; + +#endif // KIS_MOVE_EVENT_H_ + diff --git a/chalk/ui/kis_multi_bool_filter_widget.cc b/chalk/ui/kis_multi_bool_filter_widget.cc new file mode 100644 index 00000000..2507f1fb --- /dev/null +++ b/chalk/ui/kis_multi_bool_filter_widget.cc @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2005 Michael Thaler <michael.thaler@physik.tu-muenchen.de> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_multi_bool_filter_widget.h" + +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqcheckbox.h> + +#include <klocale.h> + +KisBoolWidgetParam::KisBoolWidgetParam( bool ninitvalue, TQString nlabel, TQString nname) : + initvalue(ninitvalue), + label(nlabel), + name(nname) +{ + +} + +KisMultiBoolFilterWidget::KisMultiBoolFilterWidget(TQWidget * tqparent, const char * name, const char * caption, vKisBoolWidgetParam iwparam) : + KisFilterConfigWidget( tqparent, name ) +{ + TQ_INT32 m_nbboolWidgets = iwparam.size(); + + this->setCaption(caption); + + TQVBoxLayout *widgetLayout = new TQVBoxLayout(this, m_nbboolWidgets + 1); + + m_boolWidgets = new TQCheckBox*[ m_nbboolWidgets ]; + + for( TQ_INT32 i = 0; i < m_nbboolWidgets; ++i) + { + m_boolWidgets[i] = new TQCheckBox( this, iwparam[i].name.ascii()); + m_boolWidgets[i]->setChecked( iwparam[i].initvalue ); + m_boolWidgets[i]->setText( iwparam[i].label ); + connect(m_boolWidgets[i], TQT_SIGNAL(toggled( bool ) ), TQT_SIGNAL(sigPleaseUpdatePreview())); + widgetLayout->add( m_boolWidgets[i]); + } +// TQSpacerItem * sp = new TQSpacerItem(1, 1); + widgetLayout->addStretch(); +} + + +void KisMultiBoolFilterWidget::setConfiguration(KisFilterConfiguration * config) +{ + + for (int i = 0; i < m_nbboolWidgets; ++i) { + double val = config->getBool(m_boolWidgets[i]->name()); + m_boolWidgets[i]->setChecked(val); + } +} + +#include "kis_multi_bool_filter_widget.moc" diff --git a/chalk/ui/kis_multi_bool_filter_widget.h b/chalk/ui/kis_multi_bool_filter_widget.h new file mode 100644 index 00000000..0e719bee --- /dev/null +++ b/chalk/ui/kis_multi_bool_filter_widget.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2005 Michael Thaler <michael.thaler@physik.tu-muenchen.de> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _KIS_MULTI_BOOL_FILTER_WIDGET_H_ +#define _KIS_MULTI_BOOL_FILTER_WIDGET_H_ + +#include <vector> + +#include <tqcheckbox.h> + +#include "koffice_export.h" +#include <kis_filter_config_widget.h> + +class KIntNumInput; + +struct KisBoolWidgetParam { + KRITA_EXPORT KisBoolWidgetParam( bool ninitvalue, TQString label, TQString name); + bool initvalue; + TQString label; + TQString name; + +}; + +typedef std::vector<KisBoolWidgetParam> vKisBoolWidgetParam; + +class KRITA_EXPORT KisMultiBoolFilterWidget : public KisFilterConfigWidget +{ + Q_OBJECT + TQ_OBJECT +public: + KisMultiBoolFilterWidget(TQWidget * tqparent, const char * name, const char *caption, vKisBoolWidgetParam iwparam); + virtual void setConfiguration(KisFilterConfiguration * cfg); +public: + inline TQ_INT32 nbValues() { return m_nbboolWidgets; }; + inline TQ_INT32 valueAt( TQ_INT32 i ) { return m_boolWidgets[i]->isChecked(); }; +private: + TQCheckBox** m_boolWidgets; + TQ_INT32 m_nbboolWidgets; +}; + +#endif diff --git a/chalk/ui/kis_multi_double_filter_widget.cc b/chalk/ui/kis_multi_double_filter_widget.cc new file mode 100644 index 00000000..9b5d453b --- /dev/null +++ b/chalk/ui/kis_multi_double_filter_widget.cc @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2004 Cyrille Berger <cberger@cberger.net> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_multi_double_filter_widget.h" + +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqtimer.h> + +#include <knuminput.h> +#include <kis_filter_config_widget.h> +#include <klocale.h> + +KisDelayedActionDoubleInput::KisDelayedActionDoubleInput(TQWidget * tqparent, const char * name) + : KDoubleNumInput(tqparent, name) +{ + m_timer = new TQTimer(this, name); + connect(m_timer, TQT_SIGNAL(timeout()), TQT_SLOT(slotValueChanged())); + connect(this, TQT_SIGNAL(valueChanged( double )), TQT_SLOT(slotTimeToUpdate())); +} + +void KisDelayedActionDoubleInput::slotTimeToUpdate() +{ + m_timer->start(50, true); +} + +void KisDelayedActionDoubleInput::slotValueChanged() +{ + emit valueChangedDelayed( value() ); +} + +void KisDelayedActionDoubleInput::cancelDelayedSignal() +{ + m_timer->stop(); +} + +KisDoubleWidgetParam::KisDoubleWidgetParam(double nmin, double nmax, double ninitvalue, TQString nlabel, TQString nname) : + min(nmin), + max(nmax), + initvalue(ninitvalue), + label(nlabel), + name(nname) +{ + +} + +KisMultiDoubleFilterWidget::KisMultiDoubleFilterWidget(TQWidget * tqparent, const char * name, const char * caption, vKisDoubleWidgetParam dwparam) + : KisFilterConfigWidget( tqparent, name ) +{ + TQ_INT32 m_nbdoubleWidgets = dwparam.size(); + + this->setCaption(caption); + + TQGridLayout *widgetLayout = new TQGridLayout(this, m_nbdoubleWidgets + 1, 3); + widgetLayout->setColStretch ( 1, 1 ); + + m_doubleWidgets = new KisDelayedActionDoubleInput*[ m_nbdoubleWidgets ]; + + for( TQ_INT32 i = 0; i < m_nbdoubleWidgets; ++i) + { + m_doubleWidgets[i] = new KisDelayedActionDoubleInput(this, dwparam[i].name.ascii()); + m_doubleWidgets[i]->setRange( dwparam[i].min, dwparam[i].max ); + m_doubleWidgets[i]->setValue( dwparam[i].initvalue ); + m_doubleWidgets[i]->cancelDelayedSignal(); + + connect(m_doubleWidgets[i], TQT_SIGNAL(valueChangedDelayed(double)), TQT_SIGNAL(sigPleaseUpdatePreview())); + + TQLabel* lbl = new TQLabel(dwparam[i].label+":", this); + widgetLayout->addWidget( lbl, i , 0); + + widgetLayout->addWidget( m_doubleWidgets[i], i , 1); + } + TQSpacerItem * sp = new TQSpacerItem(1, 1); + widgetLayout->addItem(sp, m_nbdoubleWidgets, 0); + +} + +void KisMultiDoubleFilterWidget::setConfiguration(KisFilterConfiguration * config) +{ + + for (int i = 0; i < m_nbdoubleWidgets ; ++i) { + double val = config->getDouble(m_doubleWidgets[i]->name()); + m_doubleWidgets[i]->setValue(val); + m_doubleWidgets[i]->cancelDelayedSignal(); + } +} + +#include "kis_multi_double_filter_widget.moc" diff --git a/chalk/ui/kis_multi_double_filter_widget.h b/chalk/ui/kis_multi_double_filter_widget.h new file mode 100644 index 00000000..5351745e --- /dev/null +++ b/chalk/ui/kis_multi_double_filter_widget.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2004 Cyrille Berger <cberger@cberger.net> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _KIS_MULTI_DOUBLE_FILTER_WIDGET_H_ +#define _KIS_MULTI_DOUBLE_FILTER_WIDGET_H_ + +#include <vector> +#include <knuminput.h> +#include <kis_filter_config_widget.h> +#include "koffice_export.h" + +class KisDelayedActionDoubleInput : public KDoubleNumInput +{ + + Q_OBJECT + TQ_OBJECT + + public: + + KisDelayedActionDoubleInput(TQWidget * tqparent, const char * name); + + void cancelDelayedSignal(); + + private slots: + void slotValueChanged(); + void slotTimeToUpdate(); + + signals: + + void valueChangedDelayed(double value); + + private: + + TQTimer * m_timer; +}; + + +struct KRITA_EXPORT KisDoubleWidgetParam { + KisDoubleWidgetParam( double nmin, double nmax, double ninitvalue, TQString label, TQString nname); + double min; + double max; + double initvalue; + TQString label; + TQString name; +}; + +typedef std::vector<KisDoubleWidgetParam> vKisDoubleWidgetParam; + +class KRITA_EXPORT KisMultiDoubleFilterWidget : public KisFilterConfigWidget +{ + Q_OBJECT + TQ_OBJECT +public: + KisMultiDoubleFilterWidget(TQWidget * tqparent, const char * name, const char * caption, vKisDoubleWidgetParam dwparam); + virtual void setConfiguration(KisFilterConfiguration * cfg); +public: + inline TQ_INT32 nbValues() { return m_nbdoubleWidgets; }; + inline double valueAt( TQ_INT32 i ) { return m_doubleWidgets[i]->value(); }; +private: + KisDelayedActionDoubleInput** m_doubleWidgets; + TQ_INT32 m_nbdoubleWidgets; +}; + +#endif diff --git a/chalk/ui/kis_multi_integer_filter_widget.cc b/chalk/ui/kis_multi_integer_filter_widget.cc new file mode 100644 index 00000000..07bfbe2a --- /dev/null +++ b/chalk/ui/kis_multi_integer_filter_widget.cc @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2004 Cyrille Berger <cberger@cberger.net> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_multi_integer_filter_widget.h" + +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqtimer.h> + +#include <knuminput.h> +#include <klocale.h> + +KisDelayedActionIntegerInput::KisDelayedActionIntegerInput(TQWidget * tqparent, const char * name) + : KIntNumInput(tqparent, name) +{ + m_timer = new TQTimer(this, name); + connect(m_timer, TQT_SIGNAL(timeout()), TQT_SLOT(slotValueChanged())); + connect(this, TQT_SIGNAL(valueChanged( int )), TQT_SLOT(slotTimeToUpdate())); +} + +void KisDelayedActionIntegerInput::slotTimeToUpdate() +{ + m_timer->start(50, true); +} + +void KisDelayedActionIntegerInput::slotValueChanged() +{ + emit valueChangedDelayed( value() ); +} + +void KisDelayedActionIntegerInput::cancelDelayedSignal() +{ + m_timer->stop(); +} + +KisIntegerWidgetParam::KisIntegerWidgetParam( TQ_INT32 nmin, TQ_INT32 nmax, TQ_INT32 ninitvalue, TQString label, TQString nname) : + min(nmin), + max(nmax), + initvalue(ninitvalue), + label(label), + name(nname) +{ +} + +KisMultiIntegerFilterWidget::KisMultiIntegerFilterWidget(TQWidget * tqparent, + const char * name, + const char * caption, + vKisIntegerWidgetParam iwparam) + : KisFilterConfigWidget( tqparent, name ) +{ + m_nbintegerWidgets = iwparam.size(); + this->setCaption(caption); + + TQGridLayout *widgetLayout = new TQGridLayout(this, m_nbintegerWidgets + 1, 3); + widgetLayout->setColStretch ( 1, 1 ); + + m_integerWidgets = new KisDelayedActionIntegerInput*[ m_nbintegerWidgets ]; + + for( TQ_INT32 i = 0; i < m_nbintegerWidgets; ++i) + { + m_integerWidgets[i] = new KisDelayedActionIntegerInput( this, iwparam[i].name.ascii()); + m_integerWidgets[i]->setRange( iwparam[i].min, iwparam[i].max); + m_integerWidgets[i]->setValue( iwparam[i].initvalue ); + m_integerWidgets[i]->cancelDelayedSignal(); + + connect(m_integerWidgets[i], TQT_SIGNAL(valueChangedDelayed( int )), TQT_SIGNAL(sigPleaseUpdatePreview())); + + TQLabel* lbl = new TQLabel(iwparam[i].label+":", this); + widgetLayout->addWidget( lbl, i , 0); + + widgetLayout->addWidget( m_integerWidgets[i], i , 1); + } + TQSpacerItem * sp = new TQSpacerItem(1, 1); + widgetLayout->addItem(sp, m_nbintegerWidgets, 0); +} + +void KisMultiIntegerFilterWidget::setConfiguration( KisFilterConfiguration * config ) +{ + for (int i = 0; i < nbValues(); ++i) { + KisDelayedActionIntegerInput * w = m_integerWidgets[i]; + if (w) { + int val = config->getInt(m_integerWidgets[i]->name()); + m_integerWidgets[i]->setValue(val); + m_integerWidgets[i]->cancelDelayedSignal(); + } + } +} + +#include "kis_multi_integer_filter_widget.moc" diff --git a/chalk/ui/kis_multi_integer_filter_widget.h b/chalk/ui/kis_multi_integer_filter_widget.h new file mode 100644 index 00000000..a08f4cad --- /dev/null +++ b/chalk/ui/kis_multi_integer_filter_widget.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2004 Cyrille Berger <cberger@cberger.net> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _KIS_MULTI_INTEGER_FILTER_WIDGET_H_ +#define _KIS_MULTI_INTEGER_FILTER_WIDGET_H_ + +#include <vector> + +#include <knuminput.h> +#include <kis_filter_config_widget.h> +#include "koffice_export.h" + +class KisDelayedActionIntegerInput : public KIntNumInput +{ + + Q_OBJECT + TQ_OBJECT + +public: + + KisDelayedActionIntegerInput(TQWidget * tqparent, const char * name); + + void cancelDelayedSignal(); + +private slots: + void slotValueChanged(); + void slotTimeToUpdate(); + +signals: + + void valueChangedDelayed(int value); + +private: + + TQTimer * m_timer; +}; + + +struct KisIntegerWidgetParam { + KRITA_EXPORT KisIntegerWidgetParam( TQ_INT32 nmin, TQ_INT32 nmax, TQ_INT32 ninitvalue, TQString label, TQString nname); + TQ_INT32 min; + TQ_INT32 max; + TQ_INT32 initvalue; + TQString label; + TQString name; +}; + +typedef std::vector<KisIntegerWidgetParam> vKisIntegerWidgetParam; + +class KRITA_EXPORT KisMultiIntegerFilterWidget : public KisFilterConfigWidget +{ + Q_OBJECT + TQ_OBJECT +public: + KisMultiIntegerFilterWidget(TQWidget * tqparent, const char * name, const char *caption, vKisIntegerWidgetParam iwparam); + + virtual void setConfiguration(KisFilterConfiguration * config); + +public: + inline TQ_INT32 nbValues() { return m_nbintegerWidgets; }; + inline TQ_INT32 valueAt( TQ_INT32 i ) { return m_integerWidgets[i]->value(); }; + +private: + TQ_INT32 m_nbintegerWidgets; + KisDelayedActionIntegerInput** m_integerWidgets; +}; + +#endif diff --git a/chalk/ui/kis_opengl_canvas.cc b/chalk/ui/kis_opengl_canvas.cc new file mode 100644 index 00000000..ef8f743e --- /dev/null +++ b/chalk/ui/kis_opengl_canvas.cc @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2005 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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.g + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_canvas.h" +#include "kis_opengl_canvas.h" +#include "kis_opengl_canvas_painter.h" + +#ifdef HAVE_GL +KisOpenGLCanvasWidget::KisOpenGLCanvasWidget(TQWidget *tqparent, const char *name, TQGLWidget *sharedContextWidget) + : TQGLWidget(KisOpenGLCanvasFormat, tqparent, name, sharedContextWidget) +{ + if (isSharing()) { + kdDebug(41001) << "Created TQGLWidget with sharing\n"; + } else { + kdDebug(41001) << "Created TQGLWidget with no sharing\n"; + } +} + +KisOpenGLCanvasWidget::~KisOpenGLCanvasWidget() +{ +} + +void KisOpenGLCanvasWidget::paintEvent(TQPaintEvent *e) +{ + TQGLWidget::paintEvent(e); + + widgetGotPaintEvent(e); +} + +void KisOpenGLCanvasWidget::mousePressEvent(TQMouseEvent *e) +{ + widgetGotMousePressEvent(e); +} + +void KisOpenGLCanvasWidget::mouseReleaseEvent(TQMouseEvent *e) +{ + widgetGotMouseReleaseEvent(e); +} + +void KisOpenGLCanvasWidget::mouseDoubleClickEvent(TQMouseEvent *e) +{ + widgetGotMouseDoubleClickEvent(e); +} + +void KisOpenGLCanvasWidget::mouseMoveEvent(TQMouseEvent *e) +{ + widgetGotMouseMoveEvent(e); +} + +void KisOpenGLCanvasWidget::tabletEvent(TQTabletEvent *e) +{ + widgetGotTabletEvent(e); +} + +void KisOpenGLCanvasWidget::enterEvent(TQEvent *e) +{ + widgetGotEnterEvent(e); +} + +void KisOpenGLCanvasWidget::leaveEvent(TQEvent *e) +{ + widgetGotLeaveEvent(e); +} + +void KisOpenGLCanvasWidget::wheelEvent(TQWheelEvent *e) +{ + widgetGotWheelEvent(e); +} + +void KisOpenGLCanvasWidget::keyPressEvent(TQKeyEvent *e) +{ + widgetGotKeyPressEvent(e); +} + +void KisOpenGLCanvasWidget::keyReleaseEvent(TQKeyEvent *e) +{ + widgetGotKeyReleaseEvent(e); +} + +void KisOpenGLCanvasWidget::dragEnterEvent(TQDragEnterEvent *e) +{ + widgetGotDragEnterEvent(e); +} + +void KisOpenGLCanvasWidget::dropEvent(TQDropEvent *e) +{ + widgetGotDropEvent(e); +} + +#ifdef Q_WS_X11 + +bool KisOpenGLCanvasWidget::x11Event(XEvent *event) +{ + return KisCanvasWidget::x11Event(event, x11Display(), winId(), mapToGlobal(TQPoint(0, 0))); +} + +#endif // Q_WS_X11 + +KisCanvasWidgetPainter *KisOpenGLCanvasWidget::createPainter() +{ + return new KisOpenGLCanvasPainter(this); +} + +#if defined(EXTENDED_X11_TABLET_SUPPORT) +void KisOpenGLCanvasWidget::selectTabletDeviceEvents() +{ + KisCanvasWidget::selectTabletDeviceEvents(this); +} +#endif + +#endif // HAVE_GL + diff --git a/chalk/ui/kis_opengl_canvas.h b/chalk/ui/kis_opengl_canvas.h new file mode 100644 index 00000000..8ca2b1e3 --- /dev/null +++ b/chalk/ui/kis_opengl_canvas.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2005 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_OPENGL_CANVAS_H_ +#define KIS_OPENGL_CANVAS_H_ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef HAVE_GL + +#include <tqwidget.h> +#include <tqgl.h> + +#include "kis_global.h" +#include "kis_canvas.h" + +#ifdef Q_MOC_RUN +#define Q_WS_X11 +#endif // Q_MOC_RUN + +#ifdef Q_WS_X11 +#include <X11/Xlib.h> +#endif // Q_WS_X11 + +#define KisOpenGLCanvasFormat (TQGL::DoubleBuffer|TQGL::Rgba|TQGL::DirectRendering|TQGL::NoDepthBuffer) + +class KisOpenGLCanvasWidget : public virtual TQGLWidget, public virtual KisCanvasWidget { +public: + KisOpenGLCanvasWidget(TQWidget *tqparent, const char *name, TQGLWidget *sharedContextWidget); + ~KisOpenGLCanvasWidget(); + + virtual KisCanvasWidgetPainter *createPainter(); + +#if defined(EXTENDED_X11_TABLET_SUPPORT) + virtual void selectTabletDeviceEvents(); +#endif + +protected: + virtual void paintEvent(TQPaintEvent *event); + virtual void mousePressEvent(TQMouseEvent *event); + virtual void mouseReleaseEvent(TQMouseEvent *event); + virtual void mouseDoubleClickEvent(TQMouseEvent *event); + virtual void mouseMoveEvent(TQMouseEvent *event); + virtual void tabletEvent(TQTabletEvent *event); + virtual void enterEvent(TQEvent *event ); + virtual void leaveEvent(TQEvent *event); + virtual void wheelEvent(TQWheelEvent *event); + virtual void keyPressEvent(TQKeyEvent *event); + virtual void keyReleaseEvent(TQKeyEvent *event); + virtual void dragEnterEvent(TQDragEnterEvent *event); + virtual void dropEvent(TQDropEvent *event); +#ifdef Q_WS_X11 + bool x11Event(XEvent *event); +#endif // Q_WS_X11 +}; +#endif // HAVE_GL + +#endif // KIS_OPENGL_CANVAS_H_ + diff --git a/chalk/ui/kis_opengl_canvas_painter.cc b/chalk/ui/kis_opengl_canvas_painter.cc new file mode 100644 index 00000000..6ae12305 --- /dev/null +++ b/chalk/ui/kis_opengl_canvas_painter.cc @@ -0,0 +1,849 @@ +/* + * Copyright (c) 2005 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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.g + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef HAVE_GL + +#include <kdebug.h> + +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_opengl_canvas_painter.h" + +KisOpenGLCanvasPainter::KisOpenGLCanvasPainter() +: m_active(false), m_widget(0) +{ +} + +KisOpenGLCanvasPainter::KisOpenGLCanvasPainter(TQGLWidget *widget) + : m_active(true), m_widget(widget) +{ + prepareForDrawing(); +} + +KisOpenGLCanvasPainter::~KisOpenGLCanvasPainter() +{ + if (m_widget) { + if (m_active) { + end(); + } + m_widget->doneCurrent(); + } +} + +bool KisOpenGLCanvasPainter::begin(KisCanvasWidget *canvasWidget, bool /*unclipped*/) +{ + m_widget = dynamic_cast<TQGLWidget *>(canvasWidget); + + if (m_widget != 0) { + prepareForDrawing(); + return true; + } else { + return false; + } + return false; +} + +void KisOpenGLCanvasPainter::prepareForDrawing() +{ + if (m_widget != 0) { + m_widget->makeCurrent(); + m_active = true; + save(); + glDrawBuffer(GL_FRONT); + glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO); + glEnable(GL_BLEND); + + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + + m_window = TQRect(0, 0, m_widget->width(), m_widget->height()); + m_viewport = m_window; + updateViewTransformation(); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + setPen(m_defaultPen); + } +} + +void KisOpenGLCanvasPainter::updateViewTransformation() +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + // We don't set the GL viewport directly from the TQt one as the GL + // has a limited size. Instead we fold it into the projection matrix. + glViewport(0, 0, m_widget->width(), m_widget->height()); + glOrtho(0, m_widget->width(), m_widget->height(), 0, -1, 1); + + glTranslatef(m_viewport.x(), m_viewport.y(), 0.0); + glScalef(static_cast<float>(m_viewport.width()) / m_window.width(), + static_cast<float>(m_viewport.height()) / m_window.height(), + 1.0); + glTranslatef(-m_window.x(), -m_window.y(), 0.0); +} + +bool KisOpenGLCanvasPainter::end() +{ + if (m_active) { + restore(); + m_active = false; + return true; + } else { + return false; + } +} + +void KisOpenGLCanvasPainter::save() +{ + glPushAttrib(GL_ALL_ATTRIB_BITS); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glMatrixMode(GL_TEXTURE); + glPushMatrix(); +} + +void KisOpenGLCanvasPainter::restore() +{ + glPopAttrib(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_TEXTURE); + glPopMatrix(); +} + +void KisOpenGLCanvasPainter::setPenStyle(Qt::PenStyle penStyle) +{ + if (penStyle == TQt::SolidLine) { + glDisable(GL_LINE_STIPPLE); + } else { + GLushort lineStipple; + + switch (penStyle) { + case TQt::NoPen: + lineStipple = 0; + break; + default: + case TQt::DashLine: + lineStipple = 0x3fff; + break; + case TQt::DotLine: + lineStipple = 0x3333; + break; + case TQt::DashDotLine: + lineStipple = 0x33ff; + break; + case TQt::DashDotDotLine: + lineStipple = 0x333f; + break; + } + + glEnable(GL_LINE_STIPPLE); + glLineStipple(1, lineStipple); + } +} + +TQFontMetrics KisOpenGLCanvasPainter::fontMetrics() const +{ + return TQFontMetrics(TQFont()); +} + +TQFontInfo KisOpenGLCanvasPainter::fontInfo() const +{ + return TQFontInfo(TQFont()); +} + +const TQFont& KisOpenGLCanvasPainter::font() const +{ + return m_defaultFont; +} + +void KisOpenGLCanvasPainter::setFont(const TQFont& /*font*/) +{ +} + +const TQPen& KisOpenGLCanvasPainter::pen() const +{ + return m_defaultPen; +} + +void KisOpenGLCanvasPainter::setPen(const TQPen& pen) +{ + setPenStyle(pen.style()); +} + +void KisOpenGLCanvasPainter::setPen(Qt::PenStyle penStyle) +{ + setPenStyle(penStyle); +} + +void KisOpenGLCanvasPainter::setPen(const TQColor& /*color*/) +{ +} + +const TQBrush& KisOpenGLCanvasPainter::brush() const +{ + return m_defaultBrush; +} + +void KisOpenGLCanvasPainter::setBrush(const TQBrush& /*brush*/) +{ +} + +void KisOpenGLCanvasPainter::setBrush(TQt::BrushStyle /*brushStyle*/) +{ +} + +void KisOpenGLCanvasPainter::setBrush(const TQColor& /*color*/) +{ +} + +TQPoint KisOpenGLCanvasPainter::pos() const +{ + return TQPoint(); +} + +const TQColor& KisOpenGLCanvasPainter::backgroundColor() const +{ + return m_defaultColor; +} + +void KisOpenGLCanvasPainter::setBackgroundColor(const TQColor& /*color*/) +{ +} + +Qt::BGMode KisOpenGLCanvasPainter::backgroundMode() const +{ + return Qt::TransparentMode; +} + +void KisOpenGLCanvasPainter::setBackgroundMode(Qt::BGMode /*bgMode*/) +{ +} + +TQt::TQt::RasterOp KisOpenGLCanvasPainter::rasterOp() const +{ + return TQt::CopyROP; +} + +void KisOpenGLCanvasPainter::setRasterOp(TQt::RasterOp /*rasterOp*/) +{ +} + +const TQPoint& KisOpenGLCanvasPainter::brushOrigin() const +{ + return m_defaultBrushOrigin; +} + +void KisOpenGLCanvasPainter::setBrushOrigin(int /*x*/, int /*y*/) +{ +} + +void KisOpenGLCanvasPainter::setBrushOrigin(const TQPoint& /*origin*/) +{ +} + +bool KisOpenGLCanvasPainter::hasViewXForm() const +{ + return false; +} + +bool KisOpenGLCanvasPainter::hasWorldXForm() const +{ + return false; +} + +void KisOpenGLCanvasPainter::setViewXForm(bool /*enable*/) +{ +} + +TQRect KisOpenGLCanvasPainter::window() const +{ + return m_window; +} + +void KisOpenGLCanvasPainter::setWindow(const TQRect& r) +{ + m_window = r; + updateViewTransformation(); +} + +void KisOpenGLCanvasPainter::setWindow(int x, int y, int w, int h) +{ + setWindow(TQRect(x, y, w, h)); +} + +TQRect KisOpenGLCanvasPainter::viewport() const +{ + return m_viewport; +} + +void KisOpenGLCanvasPainter::setViewport(const TQRect& r) +{ + m_viewport = r; + updateViewTransformation(); +} + +void KisOpenGLCanvasPainter::setViewport(int x, int y, int w, int h) +{ + setViewport(TQRect(x, y, w, h)); +} + +void KisOpenGLCanvasPainter::setWorldXForm(bool /*enable*/) +{ +} + +const TQWMatrix& KisOpenGLCanvasPainter::tqworldMatrix() const +{ + return m_defaultWorldMatrix; +} + +void KisOpenGLCanvasPainter::setWorldMatrix(const TQWMatrix& /*matrix*/, bool /*combine*/) +{ +} + +void KisOpenGLCanvasPainter::saveWorldMatrix() +{ +} + +void KisOpenGLCanvasPainter::restoreWorldMatrix() +{ +} + +void KisOpenGLCanvasPainter::scale(double /*sx*/, double /*sy*/) +{ +} + +void KisOpenGLCanvasPainter::shear(double /*sh*/, double /*sv*/) +{ +} + +void KisOpenGLCanvasPainter::rotate(double /*a*/) +{ +} + +void KisOpenGLCanvasPainter::translate(double dx, double dy) +{ + glMatrixMode(GL_MODELVIEW); + glTranslated(dx, dy, 0.0); +} + +void KisOpenGLCanvasPainter::resetXForm() +{ +} + +double KisOpenGLCanvasPainter::translationX() const +{ + return 0; +} + +double KisOpenGLCanvasPainter::translationY() const +{ + return 0; +} + +TQPoint KisOpenGLCanvasPainter::xForm(const TQPoint& point) const +{ + return point; +} + +TQRect KisOpenGLCanvasPainter::xForm(const TQRect& r) const +{ + return r; +} + +TQPointArray KisOpenGLCanvasPainter::xForm(const TQPointArray& pointArray) const +{ + return pointArray; +} + +TQPointArray KisOpenGLCanvasPainter::xForm(const TQPointArray& pointArray, int /*index*/, int /*npoints*/) const +{ + return pointArray; +} + +TQPoint KisOpenGLCanvasPainter::xFormDev(const TQPoint& point) const +{ + return point; +} + +TQRect KisOpenGLCanvasPainter::xFormDev(const TQRect& r) const +{ + return r; +} + +TQPointArray KisOpenGLCanvasPainter::xFormDev(const TQPointArray& pointArray) const +{ + return pointArray; +} + +TQPointArray KisOpenGLCanvasPainter::xFormDev(const TQPointArray& pointArray, int /*index*/, int /*npoints*/) const +{ + return pointArray; +} + +void KisOpenGLCanvasPainter::setClipping(bool /*enable*/) +{ +} + +bool KisOpenGLCanvasPainter::hasClipping() const +{ + return true; +} + +TQRegion KisOpenGLCanvasPainter::clipRegion(TQPainter::CoordinateMode /*mode*/) const +{ + return TQRegion(); +} + +void KisOpenGLCanvasPainter::setClipRect(const TQRect& /*r*/, TQPainter::CoordinateMode /*mode*/) +{ +} + +void KisOpenGLCanvasPainter::setClipRect(int /*x*/, int /*y*/, int /*w*/, int /*h*/, TQPainter::CoordinateMode /*mode*/) +{ +} + +void KisOpenGLCanvasPainter::setClipRegion(const TQRegion& /*rgn*/, TQPainter::CoordinateMode /*mode*/) +{ +} + +void KisOpenGLCanvasPainter::drawPoint(int x, int y) +{ + glBegin(GL_POINTS); + glVertex2i(x, y); + glEnd(); +} + +void KisOpenGLCanvasPainter::drawPoint(const TQPoint& point) +{ + drawPoint(point.x(), point.y()); +} + +void KisOpenGLCanvasPainter::drawPoints(const TQPointArray& pointArray, int index, int npoints) +{ + int firstPointIndex = index; + + if (firstPointIndex < 0) { + firstPointIndex = 0; + } + if (firstPointIndex > (int)pointArray.count() - 1) { + return; + } + + int lastPointIndex; + + if (npoints < 0) { + lastPointIndex = pointArray.count() - 1; + } else { + lastPointIndex = firstPointIndex + npoints; + if (lastPointIndex > (int)pointArray.count() - 1) { + lastPointIndex = pointArray.count() - 1; + } + } + + glBegin(GL_POINTS); + + for (int pointIndex = firstPointIndex; pointIndex <= lastPointIndex; pointIndex++) { + TQPoint point = pointArray.point(pointIndex); + glVertex2i(point.x(), point.y()); + } + + glEnd(); +} + +void KisOpenGLCanvasPainter::moveTo(int /*x*/, int /*y*/) +{ +} + +void KisOpenGLCanvasPainter::moveTo(const TQPoint& /*point*/) +{ +} + +void KisOpenGLCanvasPainter::lineTo(int /*x*/, int /*y*/) +{ +} + +void KisOpenGLCanvasPainter::lineTo(const TQPoint& /*point*/) +{ +} + +void KisOpenGLCanvasPainter::drawLine(int x1, int y1, int x2, int y2) +{ + glBegin(GL_LINES); + glVertex2i(x1, y1); + glVertex2i(x2, y2); + glEnd(); +} + +void KisOpenGLCanvasPainter::drawLine(const TQPoint& start, const TQPoint& end) +{ + drawLine(start.x(), start.y(), end.x(), end.y()); +} + +void KisOpenGLCanvasPainter::drawRect(int x, int y, int w, int h) +{ + glBegin(GL_LINES); + + glVertex2i(x, y); + glVertex2i(x + w - 1, y); + + glVertex2i(x + w - 1, y); + glVertex2i(x + w - 1, y + h - 1); + + glVertex2i(x + w - 1, y + h - 1); + glVertex2i(x, y + h - 1); + + glVertex2i(x, y + h - 1); + glVertex2i(x, y); + + glEnd(); +} + +void KisOpenGLCanvasPainter::drawRect(const TQRect& r) +{ + drawRect(r.x(), r.y(), r.width(), r.height()); +} + +void KisOpenGLCanvasPainter::drawWinFocusRect(int /*x*/, int /*y*/, int /*w*/, int /*h*/) +{ +} + +void KisOpenGLCanvasPainter::drawWinFocusRect(int /*x*/, int /*y*/, int /*w*/, int /*h*/, const TQColor& /*bgColor*/) +{ +} + +void KisOpenGLCanvasPainter::drawWinFocusRect(const TQRect& /*r*/) +{ +} + +void KisOpenGLCanvasPainter::drawWinFocusRect(const TQRect& /*r*/, const TQColor& /*bgColor*/) +{ +} + +void KisOpenGLCanvasPainter::drawRoundRect(int x, int y, int w, int h, int /*xRnd*/, int /*yRnd*/) +{ + glBegin(GL_LINES); + + glVertex2i(x, y); + glVertex2i(x + w - 1, y); + + glVertex2i(x + w - 1, y); + glVertex2i(x + w - 1, y + h - 1); + + glVertex2i(x + w - 1, y + h - 1); + glVertex2i(x, y + h - 1); + + glVertex2i(x, y + h - 1); + glVertex2i(x, y); + + glEnd(); +} + +void KisOpenGLCanvasPainter::drawRoundRect(const TQRect& r, int /*xRnd*/, int /*yRnd*/) +{ + drawRoundRect(r.x(), r.y(), r.width(), r.height()); +} + +// void KisOpenGLCanvasPainter::drawRoundRect(int /*x*/, int /*y*/, int /*w*/, int /*h*/, int /*xRnd*/, int /*yRnd*/) +// { +// } +// +// void KisOpenGLCanvasPainter::drawRoundRect(const TQRect& /*r*/, int /*xRnd*/, int /*yRnd*/) +// { +// } + +void KisOpenGLCanvasPainter::drawEllipse(int x, int y, int w, int h) +{ + TQRect r(x, y, w, h); + r = r.normalize(); + + TQPointArray points; + + points.makeEllipse(r.x(), r.y(), r.width(), r.height()); + drawPoints(points); +} + +void KisOpenGLCanvasPainter::drawEllipse(const TQRect& r) +{ + drawEllipse(r.x(), r.y(), r.width(), r.height()); +} + +void KisOpenGLCanvasPainter::drawArc(int /*x*/, int /*y*/, int /*w*/, int /*h*/, int /*a*/, int /*alen*/) +{ +} + +void KisOpenGLCanvasPainter::drawArc(const TQRect& /*r*/, int /*a*/, int /*alen*/) +{ +} + +void KisOpenGLCanvasPainter::drawPie(int /*x*/, int /*y*/, int /*w*/, int /*h*/, int /*a*/, int /*alen*/) +{ +} + +void KisOpenGLCanvasPainter::drawPie(const TQRect& /*r*/, int /*a*/, int /*alen*/) +{ +} + +void KisOpenGLCanvasPainter::drawChord(int /*x*/, int /*y*/, int /*w*/, int /*h*/, int /*a*/, int /*alen*/) +{ +} + +void KisOpenGLCanvasPainter::drawChord(const TQRect& /*r*/, int /*a*/, int /*alen*/) +{ +} + +void KisOpenGLCanvasPainter::drawLineSegments(const TQPointArray& /*pointArray*/, int /*index*/, int /*nlines*/) +{ +} + +void KisOpenGLCanvasPainter::drawPolyline(const TQPointArray& pointArray, int index, int npoints) +{ + int firstPointIndex = index; + + if (firstPointIndex < 0) { + firstPointIndex = 0; + } + if (firstPointIndex > (int)pointArray.count() - 2) { + return; + } + + int lastPointIndex; + + if (npoints < 0) { + lastPointIndex = pointArray.count() - 1; + } else { + lastPointIndex = firstPointIndex + npoints - 1; + if (lastPointIndex > (int)pointArray.count() - 1) { + lastPointIndex = pointArray.count() - 1; + } + } + + if (firstPointIndex >= lastPointIndex) { + return; + } + + glBegin(GL_LINES); + + for (int pointIndex = firstPointIndex; pointIndex <= lastPointIndex; pointIndex++) { + TQPoint point = pointArray.point(pointIndex); + glVertex2i(point.x(), point.y()); + } + + glEnd(); +} + +void KisOpenGLCanvasPainter::drawPolygon(const TQPointArray& /*pointArray*/, bool /*winding*/, int /*index*/, int /*npoints*/) +{ +} + +void KisOpenGLCanvasPainter::drawConvexPolygon(const TQPointArray& /*pointArray*/, int /*index*/, int /*npoints*/) +{ +} + +TQPoint midpoint (const TQPoint& P1, const TQPoint& P2) +{ + TQPoint temp; + temp.setX((P1.x()+P2.x())/2); + temp.setY((P1.y()+P2.y())/2); + return temp; +} + +#define MAX_LEVEL 5 + +void recursiveCurve (const TQPoint& P1, const TQPoint& P2, const TQPoint& P3, + const TQPoint& P4, int level, TQValueList<TQPoint>& dest) +{ + if (level > MAX_LEVEL) { + dest.append(midpoint(P1,P4)); + return; + } + + TQPoint L1, L2, L3, L4; + TQPoint H, R1, R2, R3, R4; + + L1 = P1; + L2 = midpoint(P1, P2); + H = midpoint(P2, P3); + R3 = midpoint(P3, P4); + R4 = P4; + L3 = midpoint(L2, H); + R2 = midpoint(R3, H); + L4 = midpoint(L3, R2); + R1 = L4; + recursiveCurve(L1, L2, L3, L4, level + 1, dest); + recursiveCurve(R1, R2, R3, R4, level + 1, dest); +} + +void KisOpenGLCanvasPainter::drawCubicBezier(const TQPointArray& pointArray, int index) +{ + TQPoint P1, P2, P3, P4; + TQValueList<TQPoint> dest; + P1 = pointArray[index++]; + P2 = pointArray[index++]; + P3 = pointArray[index++]; + P4 = pointArray[index]; + + recursiveCurve(P1, P2, P3, P4, 1, dest); + + glBegin(GL_LINE_STRIP); + + glVertex2i(P1.x(), P1.y()); + for (TQValueList<TQPoint>::iterator it = dest.begin(); it != dest.end(); it++) { + TQPoint point = (*it); + glVertex2i(point.x(), point.y()); + } + glVertex2i(P4.x(), P4.y()); + + glEnd(); +} + +void KisOpenGLCanvasPainter::drawPixmap(int /*x*/, int /*y*/, const TQPixmap& /*pixmap*/, int /*sx*/, int /*sy*/, int /*sw*/, int /*sh*/) +{ +} + +void KisOpenGLCanvasPainter::drawPixmap(const TQPoint& /*point*/, const TQPixmap& /*pixmap*/, const TQRect& /*sr*/) +{ +} + +void KisOpenGLCanvasPainter::drawPixmap(const TQPoint& /*point*/, const TQPixmap& /*pixmap*/) +{ +} + +void KisOpenGLCanvasPainter::drawPixmap(const TQRect& /*r*/, const TQPixmap& /*pixmap*/) +{ +} + +void KisOpenGLCanvasPainter::drawImage(int /*x*/, int /*y*/, const TQImage& /*image*/, int /*sx*/, int /*sy*/, int /*sw*/, int /*sh*/, int /*conversionFlags*/) +{ +} + +void KisOpenGLCanvasPainter::drawImage(const TQPoint& /*point*/, const TQImage& /*image*/, const TQRect& /*sr*/, int /*conversionFlags*/) +{ +} + +void KisOpenGLCanvasPainter::drawImage(const TQPoint& /*point*/, const TQImage& /*image*/, int /*conversion_flags*/) +{ +} + +void KisOpenGLCanvasPainter::drawImage(const TQRect& /*r*/, const TQImage& /*image*/) +{ +} + +void KisOpenGLCanvasPainter::drawTiledPixmap(int /*x*/, int /*y*/, int /*w*/, int /*h*/, const TQPixmap& /*pixmap*/, int /*sx*/, int /*sy*/) +{ +} + +void KisOpenGLCanvasPainter::drawTiledPixmap(const TQRect& /*r*/, const TQPixmap& /*pixmap*/, const TQPoint& /*point*/) +{ +} + +void KisOpenGLCanvasPainter::drawTiledPixmap(const TQRect& /*r*/, const TQPixmap& /*pixmap*/) +{ +} + +void KisOpenGLCanvasPainter::fillRect(int x, int y, int w, int h, const TQBrush& /*brush*/) +{ + // XXX: Set brush + glRecti(x, y, x + w, y + h); +} + +void KisOpenGLCanvasPainter::fillRect(const TQRect& r, const TQBrush& brush) +{ + fillRect(r.x(), r.y(), r.width(), r.height(), brush); +} + +void KisOpenGLCanvasPainter::eraseRect(int /*x*/, int /*y*/, int /*w*/, int /*h*/) +{ +} + +void KisOpenGLCanvasPainter::eraseRect(const TQRect& /*r*/) +{ +} + +void KisOpenGLCanvasPainter::drawText(int /*x*/, int /*y*/, const TQString& /*text*/, int /*len*/, TQPainter::TextDirection /*dir*/) +{ +} + +void KisOpenGLCanvasPainter::drawText(const TQPoint& /*point*/, const TQString& /*text*/, int /*len*/, TQPainter::TextDirection /*dir*/) +{ +} + +void KisOpenGLCanvasPainter::drawText(int /*x*/, int /*y*/, const TQString& /*text*/, int /*pos*/, int /*len*/, TQPainter::TextDirection /*dir*/) +{ +} + +void KisOpenGLCanvasPainter::drawText(const TQPoint& /*point*/, const TQString& /*text*/, int /*pos*/, int /*len*/, TQPainter::TextDirection /*dir*/) +{ +} + +void KisOpenGLCanvasPainter::drawText(int /*x*/, int /*y*/, int /*w*/, int /*h*/, int /*flags*/, const TQString& /*text*/, int /*len*/, TQRect */*br*/, TQTextParag **/*intern*/) +{ +} + +void KisOpenGLCanvasPainter::drawText(const TQRect& /*r*/, int /*flags*/, const TQString& /*text*/, int /*len*/, TQRect */*br*/, TQTextParag **/*intern*/) +{ +} + +void KisOpenGLCanvasPainter::tqdrawTextItem(int /*x*/, int /*y*/, const TQTextItem& /*ti*/, int /*textflags*/) +{ +} + +void KisOpenGLCanvasPainter::tqdrawTextItem(const TQPoint& /*p*/, const TQTextItem& /*ti*/, int /*textflags*/) +{ +} + +TQRect KisOpenGLCanvasPainter::boundingRect(int /*x*/, int /*y*/, int /*w*/, int /*h*/, int /*flags*/, const TQString& /*text*/, int /*len*/, TQTextParag **/*intern*/) +{ + return TQRect(); +} + +TQRect KisOpenGLCanvasPainter::boundingRect(const TQRect& /*r*/, int /*flags*/, const TQString& /*text*/, int /*len*/, TQTextParag **/*intern*/) +{ + return TQRect(); +} + +int KisOpenGLCanvasPainter::tabStops() const +{ + return 0; +} + +void KisOpenGLCanvasPainter::setTabStops(int /*ts*/) +{ +} + +int *KisOpenGLCanvasPainter::tabArray() const +{ + return 0; +} + +void KisOpenGLCanvasPainter::setTabArray(int */*ts*/) +{ +} + +#endif // HAVE_GL + diff --git a/chalk/ui/kis_opengl_canvas_painter.h b/chalk/ui/kis_opengl_canvas_painter.h new file mode 100644 index 00000000..47983ce2 --- /dev/null +++ b/chalk/ui/kis_opengl_canvas_painter.h @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2005 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_OPENGL_CANVAS_PAINTER_H_ +#define KIS_OPENGL_CANVAS_PAINTER_H_ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef HAVE_GL + +#include <tqwidget.h> +#include <tqgl.h> +#include <tqpainter.h> + +#include "kis_global.h" +#include "kis_canvas_painter.h" + +class KisOpenGLCanvasPainter : public KisCanvasWidgetPainter { +public: + KisOpenGLCanvasPainter(); + KisOpenGLCanvasPainter(TQGLWidget *widget); + + virtual ~KisOpenGLCanvasPainter(); + + virtual bool begin(KisCanvasWidget *canvasWidget, bool unclipped = false); + + // If we don't have OpenGL, we use the base class's no-op methods. + + virtual bool end(); + + virtual void save(); + virtual void restore(); + + virtual TQFontMetrics fontMetrics() const; + virtual TQFontInfo fontInfo() const; + + virtual const TQFont& font() const; + virtual void setFont(const TQFont&); + virtual const TQPen& pen() const; + virtual void setPen(const TQPen&); + virtual void setPen(Qt::PenStyle); + virtual void setPen(const TQColor&); + virtual const TQBrush&brush() const; + virtual void setBrush(const TQBrush&); + virtual void setBrush(TQt::BrushStyle); + virtual void setBrush(const TQColor&); + virtual TQPoint pos() const; + + virtual const TQColor& backgroundColor() const; + virtual void setBackgroundColor(const TQColor&); + virtual Qt::BGMode backgroundMode() const; + virtual void setBackgroundMode(Qt::BGMode); + virtual TQt::RasterOp rasterOp() const; + virtual void setRasterOp(TQt::RasterOp); + virtual const TQPoint& brushOrigin() const; + virtual void setBrushOrigin(int x, int y); + virtual void setBrushOrigin(const TQPoint&); + + virtual bool hasViewXForm() const; + virtual bool hasWorldXForm() const; + + virtual void setViewXForm(bool); + virtual TQRect window() const; + virtual void setWindow(const TQRect&); + virtual void setWindow(int x, int y, int w, int h); + virtual TQRect viewport() const; + virtual void setViewport(const TQRect&); + virtual void setViewport(int x, int y, int w, int h); + + virtual void setWorldXForm(bool); + virtual const TQWMatrix&tqworldMatrix() const; + virtual void setWorldMatrix(const TQWMatrix&, bool combine=FALSE); + + virtual void saveWorldMatrix(); + virtual void restoreWorldMatrix(); + + virtual void scale(double sx, double sy); + virtual void shear(double sh, double sv); + virtual void rotate(double a); + + virtual void translate(double dx, double dy); + virtual void resetXForm(); + virtual double translationX() const; + virtual double translationY() const; + + virtual TQPoint xForm(const TQPoint&) const; + virtual TQRect xForm(const TQRect&) const; + virtual TQPointArray xForm(const TQPointArray&) const; + virtual TQPointArray xForm(const TQPointArray&, int index, int npoints) const; + virtual TQPoint xFormDev(const TQPoint&) const; + virtual TQRect xFormDev(const TQRect&) const; + virtual TQPointArray xFormDev(const TQPointArray&) const; + virtual TQPointArray xFormDev(const TQPointArray&, int index, int npoints) const; + + virtual void setClipping(bool); + virtual bool hasClipping() const; + virtual TQRegion clipRegion(TQPainter::CoordinateMode = TQPainter::CoordDevice) const; + virtual void setClipRect(const TQRect&, TQPainter::CoordinateMode = TQPainter::CoordDevice); + virtual void setClipRect(int x, int y, int w, int h, TQPainter::CoordinateMode = TQPainter::CoordDevice); + virtual void setClipRegion(const TQRegion&, TQPainter::CoordinateMode = TQPainter::CoordDevice); + + virtual void drawPoint(int x, int y); + virtual void drawPoint(const TQPoint&); + virtual void drawPoints(const TQPointArray& a, int index=0, int npoints=-1); + virtual void moveTo(int x, int y); + virtual void moveTo(const TQPoint&); + virtual void lineTo(int x, int y); + virtual void lineTo(const TQPoint&); + virtual void drawLine(int x1, int y1, int x2, int y2); + virtual void drawLine(const TQPoint&, const TQPoint&); + virtual void drawRect(int x, int y, int w, int h); + virtual void drawRect(const TQRect&); + virtual void drawWinFocusRect(int x, int y, int w, int h); + virtual void drawWinFocusRect(int x, int y, int w, int h, const TQColor&bgColor); + virtual void drawWinFocusRect(const TQRect&); + virtual void drawWinFocusRect(const TQRect&, const TQColor&bgColor); + virtual void drawRoundRect(int x, int y, int w, int h, int = 25, int = 25); + virtual void drawRoundRect(const TQRect&, int = 25, int = 25); + virtual void drawEllipse(int x, int y, int w, int h); + virtual void drawEllipse(const TQRect&); + virtual void drawArc(int x, int y, int w, int h, int a, int alen); + virtual void drawArc(const TQRect&, int a, int alen); + virtual void drawPie(int x, int y, int w, int h, int a, int alen); + virtual void drawPie(const TQRect&, int a, int alen); + virtual void drawChord(int x, int y, int w, int h, int a, int alen); + virtual void drawChord(const TQRect&, int a, int alen); + virtual void drawLineSegments(const TQPointArray&, int index=0, int nlines=-1); + virtual void drawPolyline(const TQPointArray&, int index=0, int npoints=-1); + virtual void drawPolygon(const TQPointArray&, bool winding=FALSE, int index=0, int npoints=-1); + virtual void drawConvexPolygon(const TQPointArray&, int index=0, int npoints=-1); + virtual void drawCubicBezier(const TQPointArray&, int index=0); + virtual void drawPixmap(int x, int y, const TQPixmap&, int sx=0, int sy=0, int sw=-1, int sh=-1); + virtual void drawPixmap(const TQPoint&, const TQPixmap&, const TQRect&sr); + virtual void drawPixmap(const TQPoint&, const TQPixmap&); + virtual void drawPixmap(const TQRect&, const TQPixmap&); + virtual void drawImage(int x, int y, const TQImage&, int sx = 0, int sy = 0, int sw = -1, int sh = -1, int conversionFlags = 0); + virtual void drawImage(const TQPoint&, const TQImage&, const TQRect&sr, int conversionFlags = 0); + virtual void drawImage(const TQPoint&, const TQImage&, int conversion_flags = 0); + virtual void drawImage(const TQRect&, const TQImage&); + virtual void drawTiledPixmap(int x, int y, int w, int h, const TQPixmap&, int sx=0, int sy=0); + virtual void drawTiledPixmap(const TQRect&, const TQPixmap&, const TQPoint&); + virtual void drawTiledPixmap(const TQRect&, const TQPixmap&); + //virtual void drawPicture(const TQPicture&); + //virtual void drawPicture(int x, int y, const TQPicture&); + //virtual void drawPicture(const TQPoint&, const TQPicture&); + + virtual void fillRect(int x, int y, int w, int h, const TQBrush&); + virtual void fillRect(const TQRect&, const TQBrush&); + virtual void eraseRect(int x, int y, int w, int h); + virtual void eraseRect(const TQRect&); + + virtual void drawText(int x, int y, const TQString&, int len = -1, TQPainter::TextDirection dir = TQPainter::Auto); + virtual void drawText(const TQPoint&, const TQString&, int len = -1, TQPainter::TextDirection dir = TQPainter::Auto); + + virtual void drawText(int x, int y, const TQString&, int pos, int len, TQPainter::TextDirection dir = TQPainter::Auto); + virtual void drawText(const TQPoint&p, const TQString&, int pos, int len, TQPainter::TextDirection dir = TQPainter::Auto); + + virtual void drawText(int x, int y, int w, int h, int flags, const TQString&, int len = -1, TQRect *br=0, TQTextParag **intern=0); + virtual void drawText(const TQRect&, int flags, const TQString&, int len = -1, TQRect *br=0, TQTextParag **intern=0); + + virtual void tqdrawTextItem(int x, int y, const TQTextItem&ti, int textflags = 0); + virtual void tqdrawTextItem(const TQPoint& p, const TQTextItem&ti, int textflags = 0); + + virtual TQRect boundingRect(int x, int y, int w, int h, int flags, const TQString&, int len = -1, TQTextParag **intern=0); + virtual TQRect boundingRect(const TQRect&, int flags, const TQString&, int len = -1, TQTextParag **intern=0); + + virtual int tabStops() const; + virtual void setTabStops(int); + virtual int *tabArray() const; + virtual void setTabArray(int *); + +protected: + void prepareForDrawing(); + void updateViewTransformation(); + void setPenStyle(Qt::PenStyle penStyle); + +protected: + TQFont m_defaultFont; + TQPen m_defaultPen; + TQBrush m_defaultBrush; + TQColor m_defaultColor; + TQPoint m_defaultBrushOrigin; + TQWMatrix m_defaultWorldMatrix; + TQRect m_window; + TQRect m_viewport; + bool m_active; + +protected: + TQGLWidget *m_widget; +}; + +#endif // HAVE_GL + +#endif // KIS_OPENGL_CANVAS_PAINTER_H_ + diff --git a/chalk/ui/kis_opengl_image_context.cc b/chalk/ui/kis_opengl_image_context.cc new file mode 100644 index 00000000..6a302192 --- /dev/null +++ b/chalk/ui/kis_opengl_image_context.cc @@ -0,0 +1,371 @@ +/* + * Copyright (c) 2005 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef HAVE_GL + +#include <kdebug.h> +#include <ksharedptr.h> + +#include "kis_global.h" +#include "kis_meta_registry.h" +#include "kis_colorspace_factory_registry.h" +#include "kis_image.h" +#include "kis_layer.h" +#include "kis_selection.h" +#include "kis_background.h" +#include "kis_opengl_canvas.h" +#include "kis_opengl_image_context.h" + +using namespace std; + +TQGLWidget *KisOpenGLImageContext::SharedContextWidget = 0; +int KisOpenGLImageContext::SharedContextWidgetRefCount = 0; + +KisOpenGLImageContext::ImageContextMap KisOpenGLImageContext::imageContextMap; + +KisOpenGLImageContext::KisOpenGLImageContext() +{ + m_image = 0; + m_monitorProfile = 0; + m_exposure = 0; +} + +KisOpenGLImageContext::~KisOpenGLImageContext() +{ + kdDebug(41001) << "Destroyed KisOpenGLImageContext\n"; + + --SharedContextWidgetRefCount; + kdDebug(41001) << "Shared context widget ref count now " << SharedContextWidgetRefCount << endl; + + if (SharedContextWidgetRefCount == 0) { + + kdDebug(41001) << "Deleting shared context widget\n"; + delete SharedContextWidget; + SharedContextWidget = 0; + } + + imageContextMap.erase(m_image); +} + +KisOpenGLImageContext::KisOpenGLImageContext(KisImageSP image, KisProfile *monitorProfile) +{ + kdDebug(41001) << "Created KisOpenGLImageContext\n"; + + m_image = image; + m_monitorProfile = monitorProfile; + m_exposure = 0; + m_displaySelection = true; + + if (SharedContextWidget == 0) { + kdDebug(41001) << "Creating shared context widget\n"; + + SharedContextWidget = new TQGLWidget(KisOpenGLCanvasFormat); + } + + ++SharedContextWidgetRefCount; + + kdDebug(41001) << "Shared context widget ref count now " << SharedContextWidgetRefCount << endl; + + SharedContextWidget->makeCurrent(); + glGenTextures(1, &m_backgroundTexture); + generateBackgroundTexture(); + + GLint max_texture_size; + + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); + + m_imageTextureTileWidth = TQMIN(PREFERRED_IMAGE_TEXTURE_WIDTH, max_texture_size); + m_imageTextureTileHeight = TQMIN(PREFERRED_IMAGE_TEXTURE_HEIGHT, max_texture_size); + + createImageTextureTiles(); + + connect(m_image, TQT_SIGNAL(sigImageUpdated(TQRect)), + TQT_SLOT(slotImageUpdated(TQRect))); + connect(m_image, TQT_SIGNAL(sigSizeChanged(TQ_INT32, TQ_INT32)), + TQT_SLOT(slotImageSizeChanged(TQ_INT32, TQ_INT32))); + + updateImageTextureTiles(m_image->bounds()); +} + +KisOpenGLImageContextSP KisOpenGLImageContext::getImageContext(KisImageSP image, KisProfile *monitorProfile) +{ + if (imageCanShareImageContext(image)) { + ImageContextMap::iterator it = imageContextMap.find(image); + + if (it != imageContextMap.end()) { + + kdDebug(41001) << "Sharing image context from map\n"; + + KisOpenGLImageContextSP context = (*it).second; + context->setMonitorProfile(monitorProfile); + + return context; + } else { + KisOpenGLImageContext *imageContext = new KisOpenGLImageContext(image, monitorProfile); + imageContextMap[image] = imageContext; + + kdDebug(41001) << "Added shareable context to map\n"; + + return imageContext; + } + } else { + kdDebug(41001) << "Creating non-shareable image context\n"; + + return new KisOpenGLImageContext(image, monitorProfile); + } +} + +bool KisOpenGLImageContext::imageCanShareImageContext(KisImageSP image) +{ + if (image->colorSpace()->hasHighDynamicRange()) { + //XXX: and we don't have shaders... + return false; + } else { + return true; + } +} + +TQGLWidget *KisOpenGLImageContext::sharedContextWidget() const +{ + return SharedContextWidget; +} + +void KisOpenGLImageContext::updateImageTextureTiles(const TQRect& rect) +{ + //kdDebug() << "updateImageTextureTiles " << rect << endl; + + TQRect updateRect = rect & m_image->bounds(); + + if (!updateRect.isEmpty()) { + + SharedContextWidget->makeCurrent(); + + int firstColumn = updateRect.left() / m_imageTextureTileWidth; + int lastColumn = updateRect.right() / m_imageTextureTileWidth; + int firstRow = updateRect.top() / m_imageTextureTileHeight; + int lastRow = updateRect.bottom() / m_imageTextureTileHeight; + + for (int column = firstColumn; column <= lastColumn; column++) { + for (int row = firstRow; row <= lastRow; row++) { + + TQRect tileRect(column * m_imageTextureTileWidth, row * m_imageTextureTileHeight, + m_imageTextureTileWidth, m_imageTextureTileHeight); + + TQRect tileUpdateRect = tileRect & updateRect; + + glBindTexture(GL_TEXTURE_2D, imageTextureTile(tileRect.x(), tileRect.y())); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);//GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + TQImage tileUpdateImage = m_image->convertToTQImage(tileUpdateRect.left(), tileUpdateRect.top(), + tileUpdateRect.right(), tileUpdateRect.bottom(), + m_monitorProfile, m_exposure); + + if (m_displaySelection) { + if (m_image->activeLayer() != 0) { + m_image->activeLayer()->paintSelection(tileUpdateImage, + tileUpdateRect.x(), tileUpdateRect.y(), + tileUpdateRect.width(), tileUpdateRect.height()); + } + } + + if (tileUpdateRect.width() == m_imageTextureTileWidth && tileUpdateRect.height() == m_imageTextureTileHeight) { + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_imageTextureTileWidth, m_imageTextureTileHeight, 0, + GL_BGRA, GL_UNSIGNED_BYTE, tileUpdateImage.bits()); + } else { + int xOffset = tileUpdateRect.x() - tileRect.x(); + int yOffset = tileUpdateRect.y() - tileRect.y(); + + glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, tileUpdateRect.width(), tileUpdateRect.height(), + GL_BGRA, GL_UNSIGNED_BYTE, tileUpdateImage.bits()); + } + + GLenum error = glGetError (); + + if (error != GL_NO_ERROR) + { + kdDebug(41001) << "Error loading texture: " << endl; + } + } + } + } +} + +KisColorSpace* KisOpenGLImageContext::textureColorSpaceForImageColorSpace(KisColorSpace */*imageColorSpace*/) +{ + return KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA", ""), ""); +} + +void KisOpenGLImageContext::setMonitorProfile(KisProfile *monitorProfile) +{ + if (monitorProfile != m_monitorProfile) { + m_monitorProfile = monitorProfile; + generateBackgroundTexture(); + updateImageTextureTiles(m_image->bounds()); + } +} + +void KisOpenGLImageContext::setHDRExposure(float exposure) +{ + if (exposure != m_exposure) { + m_exposure = exposure; + + if (m_image->colorSpace()->hasHighDynamicRange()) { + //XXX: and we are not using shaders... + updateImageTextureTiles(m_image->bounds()); + } + } +} + +void KisOpenGLImageContext::generateBackgroundTexture() +{ + SharedContextWidget->makeCurrent(); + + glBindTexture(GL_TEXTURE_2D, m_backgroundTexture); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + TQImage backgroundImage = m_image->background()->patternTile(); + + // XXX: temp. + Q_ASSERT(backgroundImage.width() == BACKGROUND_TEXTURE_WIDTH); + Q_ASSERT(backgroundImage.height() == BACKGROUND_TEXTURE_HEIGHT); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, BACKGROUND_TEXTURE_WIDTH, BACKGROUND_TEXTURE_HEIGHT, 0, + GL_BGRA, GL_UNSIGNED_BYTE, backgroundImage.bits()); +} + +GLuint KisOpenGLImageContext::backgroundTexture() const +{ + return m_backgroundTexture; +} + +int KisOpenGLImageContext::imageTextureTileIndex(int x, int y) const +{ + int column = x / m_imageTextureTileWidth; + int row = y / m_imageTextureTileHeight; + + return column + (row * m_numImageTextureTileColumns); +} + +GLuint KisOpenGLImageContext::imageTextureTile(int pixelX, int pixelY) const +{ + TQ_INT32 textureTileIndex = imageTextureTileIndex(pixelX, pixelY); + + textureTileIndex = CLAMP(textureTileIndex, 0, ((TQ_INT32)m_imageTextureTiles.count()) - 1); + + return m_imageTextureTiles[textureTileIndex]; +} + +int KisOpenGLImageContext::imageTextureTileWidth() const +{ + return m_imageTextureTileWidth; +} + +int KisOpenGLImageContext::imageTextureTileHeight() const +{ + return m_imageTextureTileHeight; +} + +void KisOpenGLImageContext::createImageTextureTiles() +{ + SharedContextWidget->makeCurrent(); + + destroyImageTextureTiles(); + + m_numImageTextureTileColumns = (m_image->width() + m_imageTextureTileWidth - 1) / m_imageTextureTileWidth; + int numImageTextureTileRows = (m_image->height() + m_imageTextureTileHeight - 1) / m_imageTextureTileHeight; + int numImageTextureTiles = m_numImageTextureTileColumns * numImageTextureTileRows; + + m_imageTextureTiles.resize(numImageTextureTiles); + glGenTextures(numImageTextureTiles, &(m_imageTextureTiles[0])); + + //XXX: will be float/half with shaders + #define RGBA_BYTES_PER_PIXEL 4 + + TQByteArray emptyTilePixelData(m_imageTextureTileWidth * m_imageTextureTileHeight * RGBA_BYTES_PER_PIXEL); + emptyTilePixelData.fill(0); + + for (int tileIndex = 0; tileIndex < numImageTextureTiles; ++tileIndex) { + + glBindTexture(GL_TEXTURE_2D, m_imageTextureTiles[tileIndex]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_imageTextureTileWidth, m_imageTextureTileHeight, 0, + GL_BGRA, GL_UNSIGNED_BYTE, &emptyTilePixelData[0]); + } +} + +void KisOpenGLImageContext::destroyImageTextureTiles() +{ + if (!m_imageTextureTiles.empty()) { + SharedContextWidget->makeCurrent(); + glDeleteTextures(m_imageTextureTiles.count(), &(m_imageTextureTiles[0])); + m_imageTextureTiles.clear(); + } +} + +void KisOpenGLImageContext::update(const TQRect& imageRect) +{ + updateImageTextureTiles(imageRect); +} + +void KisOpenGLImageContext::setSelectionDisplayEnabled(bool enable) +{ + m_displaySelection = enable; +} + +void KisOpenGLImageContext::slotImageUpdated(TQRect rc) +{ + TQRect r = rc & m_image->bounds(); + + updateImageTextureTiles(r); + emit sigImageUpdated(r); +} + +void KisOpenGLImageContext::slotImageSizeChanged(TQ_INT32 w, TQ_INT32 h) +{ + createImageTextureTiles(); + updateImageTextureTiles(m_image->bounds()); + + emit sigSizeChanged(w, h); +} + +#include "kis_opengl_image_context.moc" + +#endif // HAVE_GL + diff --git a/chalk/ui/kis_opengl_image_context.h b/chalk/ui/kis_opengl_image_context.h new file mode 100644 index 00000000..03833cd2 --- /dev/null +++ b/chalk/ui/kis_opengl_image_context.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2005 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_OPENGL_IMAGE_CONTEXT_H_ +#define KIS_OPENGL_IMAGE_CONTEXT_H_ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef HAVE_GL + +#include <map> + +#include <tqgl.h> +#include <tqobject.h> +#include <tqvaluevector.h> + +#include <koffice_export.h> + +#include "kis_types.h" + +class TQRegion; + +class KisOpenGLImageContext; +typedef KSharedPtr<KisOpenGLImageContext> KisOpenGLImageContextSP; +class KisColorSpace; + +class KRITACORE_EXPORT KisOpenGLImageContext : public TQObject , public KShared { + + Q_OBJECT + TQ_OBJECT + +public: + static KisOpenGLImageContextSP getImageContext(KisImageSP image, KisProfile *monitorProfile); + + KisOpenGLImageContext(); + virtual ~KisOpenGLImageContext(); + +public: + // In order to use the image textures, the caller must pass + // the sharedContextWidget() as the shareWidget argument to the + // TQGLWidget constructor. + TQGLWidget *sharedContextWidget() const; + + void setMonitorProfile(KisProfile *profile); + void setHDRExposure(float exposure); + + GLuint backgroundTexture() const; + + static const int BACKGROUND_TEXTURE_WIDTH = 32; + static const int BACKGROUND_TEXTURE_HEIGHT = 32; + + // Get the image texture tile containing the point (pixelX, pixelY). + GLuint imageTextureTile(int pixelX, int pixelY) const; + + int imageTextureTileWidth() const; + int imageTextureTileHeight() const; + + /** + * Select selection visualisation rendering. + * + * @param enable Set to true to enable selection visualisation rendering. + */ + void setSelectionDisplayEnabled(bool enable); + + /** + * Update the image textures for the given image rectangle. + * + * @param imageRect The rectangle to update in image coordinates. + */ + void update(const TQRect& imageRect); + +signals: + /** + * Clients using the KisOpenGLImageContext should connect to the + * following signals rather than to the KisImage's own equivalent + * signals. This ensures that the image textures are always up to date + * when used. + */ + + /** + * Emitted whenever an action has caused the image to be recomposited. + * + * @param rc The rect that has been recomposited. + */ + void sigImageUpdated(TQRect rc); + + /** + * Emitted whenever the image size changes. + * + * @param width New image width + * @param height New image height + */ + void sigSizeChanged(TQ_INT32 width, TQ_INT32 height); + +protected: + KisOpenGLImageContext(KisImageSP image, KisProfile *monitorProfile); + + void generateBackgroundTexture(); + void createImageTextureTiles(); + void destroyImageTextureTiles(); + int imageTextureTileIndex(int x, int y) const; + void updateImageTextureTiles(const TQRect& rect); + + static KisColorSpace* textureColorSpaceForImageColorSpace(KisColorSpace *imageColorSpace); + static bool imageCanShareImageContext(KisImageSP image); + +protected slots: + void slotImageUpdated(TQRect r); + void slotImageSizeChanged(TQ_INT32 w, TQ_INT32 h); + +private: + KisImageSP m_image; + KisProfile *m_monitorProfile; + float m_exposure; + bool m_displaySelection; + + GLuint m_backgroundTexture; + + static const int PREFERRED_IMAGE_TEXTURE_WIDTH = 256; + static const int PREFERRED_IMAGE_TEXTURE_HEIGHT = 256; + + TQValueVector<GLuint> m_imageTextureTiles; + int m_imageTextureTileWidth; + int m_imageTextureTileHeight; + int m_numImageTextureTileColumns; + + // We create a single OpenGL context and share it between all views + // in the process. Aptqparently with some OpenGL implementations, only + // one context will be hardware accelerated. + static TQGLWidget *SharedContextWidget; + static int SharedContextWidgetRefCount; + + typedef std::map<KisImageSP, KisOpenGLImageContext*> ImageContextMap; + + static ImageContextMap imageContextMap; +}; + +#endif // HAVE_GL + +#endif // KIS_OPENGL_IMAGE_CONTEXT_H_ + diff --git a/chalk/ui/kis_paintop_box.cc b/chalk/ui/kis_paintop_box.cc new file mode 100644 index 00000000..9f8ac9de --- /dev/null +++ b/chalk/ui/kis_paintop_box.cc @@ -0,0 +1,249 @@ +/* + * kis_paintop_box.cc - part of KImageShop/Krayon/Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include <tqwidget.h> +#include <tqstring.h> +#include <tqvaluelist.h> +#include <tqpixmap.h> +#include <tqlayout.h> +#include <tqtooltip.h> + +#include <klocale.h> +#include <kactioncollection.h> +#include <kdebug.h> +#include <kglobal.h> +#include <klocale.h> +#include <kglobalsettings.h> +#include <kaccelmanager.h> +#include <kconfig.h> +#include <kstandarddirs.h> + +#include <kis_paintop_registry.h> +#include <kis_view.h> +#include <kis_painter.h> +#include <kis_paintop.h> +#include <kis_layer.h> +#include <kis_factory.h> + +#include "kis_paintop_box.h" + +KisPaintopBox::KisPaintopBox (KisView * view, TQWidget *tqparent, const char * name) + : super (tqparent, name), + m_canvasController(view->getCanvasController()) +{ +#if KDE_VERSION >= KDE_MAKE_VERSION(3,3,90) + KAcceleratorManager::setNoAccel(this); +#endif + + Q_ASSERT(m_canvasController != 0); + + setCaption(i18n("Painter's Toolchest")); + m_optionWidget = 0; + m_paintops = new TQValueList<KisID>(); + m_displayedOps = new TQValueList<KisID>(); + + m_cmbPaintops = new TQComboBox(this, "KisPaintopBox::m_cmbPaintops"); + m_cmbPaintops->setMinimumWidth(150); + TQToolTip::add(m_cmbPaintops, i18n("Styles of painting for the painting tools")); + m_layout = new TQHBoxLayout(this, 1, 1); + m_layout->addWidget(m_cmbPaintops); + + connect(this, TQT_SIGNAL(selected(const KisID &, const KisPaintOpSettings *)), view, TQT_SLOT(paintopActivated(const KisID &, const KisPaintOpSettings *))); + connect(m_cmbPaintops, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotItemSelected(int))); + + // XXX: Let's see... Are all paintops loaded and ready? + KisIDList keys = KisPaintOpRegistry::instance()->listKeys(); + for ( KisIDList::Iterator it = keys.begin(); it != keys.end(); ++it ) { + // add all paintops, and show/hide them afterwards + addItem(*it); + } + + connect(view, TQT_SIGNAL(currentColorSpaceChanged(KisColorSpace*)), + this, TQT_SLOT(colorSpaceChanged(KisColorSpace*))); + connect(view, TQT_SIGNAL(sigInputDeviceChanged(const KisInputDevice&)), + this, TQT_SLOT(slotInputDeviceChanged(const KisInputDevice&))); + + setCurrentPaintop(defaultPaintop(m_canvasController->currentInputDevice())); +} + +KisPaintopBox::~KisPaintopBox() +{ + delete m_paintops; + delete m_displayedOps; +} + +void KisPaintopBox::addItem(const KisID & paintop, const TQString & /*category*/) +{ + m_paintops->append(paintop); +} + +void KisPaintopBox::slotItemSelected(int index) +{ + if ((uint)index > m_displayedOps->count()) { + return; + } + + KisID paintop = *m_displayedOps->at(index); + + setCurrentPaintop(paintop); +} + +void KisPaintopBox::colorSpaceChanged(KisColorSpace *cs) +{ + TQValueList<KisID>::iterator it = m_paintops->begin(); + TQValueList<KisID>::iterator end = m_paintops->end(); + m_displayedOps->clear(); + m_cmbPaintops->clear(); + + for ( ; it != end; ++it ) { + if (KisPaintOpRegistry::instance()->userVisible(*it, cs)) { + TQPixmap pm = paintopPixmap(*it); + if (pm.isNull()) { + TQPixmap p = TQPixmap( 16, 16 ); + p.fill(); + m_cmbPaintops->insertItem(p, (*it).name()); + } + else { + m_cmbPaintops->insertItem(pm, (*it).name()); + } + m_displayedOps->append(*it); + } + } + + int index = m_displayedOps->tqfindIndex(currentPaintop()); + + if (index == -1) { + // Must change the paintop as the current one is not supported + // by the new colourspace. + index = 0; + } + + m_cmbPaintops->setCurrentItem( index ); + slotItemSelected( index ); +} + +TQPixmap KisPaintopBox::paintopPixmap(const KisID & paintop) +{ + TQString pixmapName = KisPaintOpRegistry::instance()->pixmap(paintop); + + if (pixmapName.isEmpty()) { + return TQPixmap(); + } + + TQString fname = KisFactory::instance()->dirs()->findResource("kis_images", pixmapName); + + return TQPixmap(fname); +} + +void KisPaintopBox::slotInputDeviceChanged(const KisInputDevice & inputDevice) +{ + KisID paintop; + InputDevicePaintopMap::iterator it = m_currentID.find(inputDevice); + + if (it == m_currentID.end()) { + paintop = defaultPaintop(inputDevice); + } else { + paintop = (*it).second; + } + + int index = m_displayedOps->tqfindIndex(paintop); + + if (index == -1) { + // Must change the paintop as the current one is not supported + // by the new colourspace. + index = 0; + paintop = *m_displayedOps->at(index); + } + + m_cmbPaintops->setCurrentItem(index); + setCurrentPaintop(paintop); +} + +void KisPaintopBox::updateOptionWidget() +{ + if (m_optionWidget != 0) { + m_layout->remove(m_optionWidget); + m_optionWidget->hide(); + m_layout->tqinvalidate(); + } + + const KisPaintOpSettings *settings = paintopSettings(currentPaintop(), m_canvasController->currentInputDevice()); + + if (settings != 0) { + m_optionWidget = settings->widget(); + Q_ASSERT(m_optionWidget != 0); + + m_layout->addWidget(m_optionWidget); + updateGeometry(); + m_optionWidget->show(); + } +} + +const KisID& KisPaintopBox::currentPaintop() +{ + return m_currentID[m_canvasController->currentInputDevice()]; +} + +void KisPaintopBox::setCurrentPaintop(const KisID & paintop) +{ + m_currentID[m_canvasController->currentInputDevice()] = paintop; + + updateOptionWidget(); + + emit selected(paintop, paintopSettings(paintop, m_canvasController->currentInputDevice())); +} + +KisID KisPaintopBox::defaultPaintop(const KisInputDevice& inputDevice) +{ + if (inputDevice == KisInputDevice::eraser()) { + return KisID("eraser",""); + } else { + return KisID("paintbrush",""); + } +} + +const KisPaintOpSettings *KisPaintopBox::paintopSettings(const KisID & paintop, const KisInputDevice & inputDevice) +{ + TQValueVector<KisPaintOpSettings *> settingsArray; + InputDevicePaintopSettingsMap::iterator it = m_inputDevicePaintopSettings.find(inputDevice); + + if (it == m_inputDevicePaintopSettings.end()) { + // Create settings for each paintop. + + for (TQValueList<KisID>::const_iterator pit = m_paintops->begin(); pit != m_paintops->end(); ++pit) { + KisPaintOpSettings *settings = KisPaintOpRegistry::instance()->settings(*pit, this, inputDevice); + settingsArray.append(settings); + if (settings && settings->widget()) { + settings->widget()->hide(); + } + } + m_inputDevicePaintopSettings[inputDevice] = settingsArray; + } else { + settingsArray = (*it).second; + } + + const int index = m_paintops->tqfindIndex(paintop); + if (index >= 0 && index < (int)settingsArray.count()) + return settingsArray[index]; + else + return 0; +} + +#include "kis_paintop_box.moc" + diff --git a/chalk/ui/kis_paintop_box.h b/chalk/ui/kis_paintop_box.h new file mode 100644 index 00000000..90238c78 --- /dev/null +++ b/chalk/ui/kis_paintop_box.h @@ -0,0 +1,104 @@ +/* + * kis_paintop_box.h - part of KImageShop/Krayon/Chalk + * + * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org) + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_PAINTOP_BOX_H_ +#define KIS_PAINTOP_BOX_H_ + +#include <map> + +#include <tqwidget.h> +#include <tqcombobox.h> +#include <tqvaluelist.h> + +#include "kis_input_device.h" + +class TQString; + +class KWidgetAction; +class KisView; +class KisCanvasController; +class KisID; +class KisColorSpace; + +/** + * This widget presents all paintops that a user can paint with. + * Paintops represent real-world tools or the well-known Shoup + * computer equivalents that do nothing but change color. + * + * XXX: When we have a lot of paintops, replace the listbox + * with a table, and for every category a combobox. + * + * XXX: instead of text, use pretty pictures. + */ +class KisPaintopBox : public TQWidget { + + Q_OBJECT + TQ_OBJECT + + typedef TQWidget super; + +public: + KisPaintopBox (KisView * view, TQWidget * tqparent, const char * name = 0); + + ~KisPaintopBox(); + + +signals: + + void selected(const KisID & id, const KisPaintOpSettings *settings); + +private slots: + + void addItem(const KisID & paintop, const TQString & category = ""); + +private slots: + + void slotItemSelected(int index); + void colorSpaceChanged(KisColorSpace *cs); + void slotInputDeviceChanged(const KisInputDevice & inputDevice); + +private: + TQPixmap paintopPixmap(const KisID & paintop); + void updateOptionWidget(); + const KisID & currentPaintop(); + void setCurrentPaintop(const KisID & paintop); + KisID defaultPaintop(const KisInputDevice& inputDevice); + const KisPaintOpSettings *paintopSettings(const KisID & paintop, const KisInputDevice & inputDevice); + +private: + KisCanvasController *m_canvasController; + TQComboBox * m_cmbPaintops; + TQHBoxLayout * m_layout; + TQWidget * m_optionWidget; + + TQValueList<KisID> * m_paintops; + TQValueList<KisID> * m_displayedOps; + + typedef std::map<KisInputDevice, KisID> InputDevicePaintopMap; + InputDevicePaintopMap m_currentID; + + typedef std::map<KisInputDevice, TQValueVector<KisPaintOpSettings *> > InputDevicePaintopSettingsMap; + InputDevicePaintopSettingsMap m_inputDevicePaintopSettings; +}; + + + +#endif //KIS_PAINTOP_BOX_H_ + diff --git a/chalk/ui/kis_palette_view.cc b/chalk/ui/kis_palette_view.cc new file mode 100644 index 00000000..dfc75eb4 --- /dev/null +++ b/chalk/ui/kis_palette_view.cc @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org> + * (c) 2005 Bart Coppens <kde@bartcoppens.be> + * + * Based on already much changed code by Waldo Bastian <bastian@kde.org> from KisPaletteWidget + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <stdio.h> +#include <stdlib.h> + +#include <tqcheckbox.h> +#include <tqcombobox.h> +#include <tqdrawutil.h> +#include <tqevent.h> +#include <tqfile.h> +#include <tqimage.h> +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqlineedit.h> +#include <tqvalidator.h> +#include <tqpainter.h> +#include <tqpushbutton.h> +#include <tqspinbox.h> +#include <tqtimer.h> + +#include <kapplication.h> +#include <kconfig.h> +#include <kglobal.h> +#include <kglobalsettings.h> +#include <kiconloader.h> +#include <klistbox.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kseparator.h> +#include <kpalette.h> +#include <kimageeffect.h> + +#include <kcolordialog.h> +#include <kcolordrag.h> +#include <config.h> +#include <kdebug.h> + +#include <kis_meta_registry.h> +#include <kis_color.h> +#include <kis_factory.h> +#include <kis_colorspace_factory_registry.h> +#include "kis_palette_view.h" +#include "kis_resource.h" +#include "kis_palette.h" + +KisPaletteView::KisPaletteView(TQWidget *tqparent, const char* name, int minWidth, int cols) + : TQScrollView( tqparent, name ), mMinWidth(minWidth), mCols(cols) +{ + m_cells = 0; + m_currentPalette = 0; + + TQSize cellSize = TQSize( mMinWidth, 50); + + setHScrollBarMode(TQScrollView::AlwaysOff); + setVScrollBarMode(TQScrollView::AlwaysOn); + + TQSize minSize = TQSize(verticalScrollBar()->width(), 0); + minSize += TQSize(frameWidth(), 0); + minSize += TQSize(cellSize); + + setMinimumSize(minSize); + tqsetSizePolicy(TQSizePolicy(TQSizePolicy::Ignored, TQSizePolicy::Ignored)); +} + +KisPaletteView::~KisPaletteView() +{ +} + +KisPalette* KisPaletteView::palette() const +{ + return m_currentPalette; +} + +void KisPaletteView::setPalette(KisPalette* palette) +{ + m_currentPalette = palette; + delete m_cells; + + int rows = (m_currentPalette->nColors() + mCols -1 ) / mCols; + + if (rows < 1) rows = 1; + + m_cells = new KColorCells(viewport(), rows, mCols); + Q_CHECK_PTR(m_cells); + + m_cells->setShading(false); + m_cells->setAcceptDrags(false); + + TQSize cellSize = TQSize( mMinWidth, mMinWidth * rows / mCols); + m_cells->setFixedSize( cellSize ); + + for( int i = 0; i < m_currentPalette->nColors(); i++) + { + TQColor c = m_currentPalette->getColor(i).color; + m_cells->setColor( i, c ); + } + + connect(m_cells, TQT_SIGNAL(colorSelected(int)), + TQT_SLOT(slotColorCellSelected(int))); + + connect(m_cells, TQT_SIGNAL(colorDoubleClicked(int)), + TQT_SLOT(slotColorCellDoubleClicked(int)) ); + + addChild( m_cells ); + m_cells->show(); + updateScrollBars(); +} + +void KisPaletteView::slotColorCellSelected( int col ) +{ + KisColorSpace * cs = KisMetaRegistry::instance()->csRegistry()->getRGB8(); + if (!m_currentPalette || (col >= m_currentPalette->nColors())) + return; + + m_currentEntry = m_currentPalette->getColor(col); + emit colorSelected(KisColor(m_currentPalette->getColor(col).color, cs)); + emit colorSelected(m_currentPalette->getColor(col).color); +} + +void KisPaletteView::slotColorCellDoubleClicked( int col ) +{ + KisColorSpace * cs = KisMetaRegistry::instance()->csRegistry()->getRGB8(); + if (!m_currentPalette || (col >= m_currentPalette->nColors())) + return; + + emit colorDoubleClicked(KisColor(m_currentPalette->getColor(col).color, cs), + m_currentPalette->getColor(col).name); +} + +#include "kis_palette_view.moc" + diff --git a/chalk/ui/kis_palette_view.h b/chalk/ui/kis_palette_view.h new file mode 100644 index 00000000..79b3e0b0 --- /dev/null +++ b/chalk/ui/kis_palette_view.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2005 Bart Coppens <kde@bartcoppens.be> + * (c) 2005 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __KIS_PALETTE_VIEW_H__ +#define __KIS_PALETTE_VIEW_H__ + +#include <tqscrollview.h> +#include "kis_palette.h" + +class KListBox; +class KisPalette; +class KColorCells; +class KisResource; +class KisColor; + +/** + * A scrolling view that lists a single KisPalette + */ +class KisPaletteView : public TQScrollView +{ + Q_OBJECT + TQ_OBJECT +public: + KisPaletteView(TQWidget *tqparent, const char* name = 0, int minWidth=210, int cols = 16); + virtual ~KisPaletteView(); + + KisPalette* palette() const; + /// Might return the default constructed entry... + KisPaletteEntry currentEntry() const { return m_currentEntry; } + +public slots: + void setPalette(KisPalette* p); + +signals: + void colorSelected(const KisColor &); + void colorSelected(const TQColor &); + void colorDoubleClicked(const KisColor &, const TQString &); + +protected slots: + void slotColorCellSelected( int ); + void slotColorCellDoubleClicked( int ); + +protected: + KisPalette* m_currentPalette; + KColorCells* m_cells; + KisPaletteEntry m_currentEntry; + int mMinWidth; + int mCols; + + friend class KisPaletteWidget; // Because it calls slotColorCellSelected from a FIXME +}; + +#endif + diff --git a/chalk/ui/kis_palette_widget.cc b/chalk/ui/kis_palette_widget.cc new file mode 100644 index 00000000..a8305337 --- /dev/null +++ b/chalk/ui/kis_palette_widget.cc @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <stdio.h> +#include <stdlib.h> + +#include <tqcheckbox.h> +#include <tqcombobox.h> +#include <tqdrawutil.h> +#include <tqevent.h> +#include <tqfile.h> +#include <tqimage.h> +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqlineedit.h> +#include <tqvalidator.h> +#include <tqpainter.h> +#include <tqpushbutton.h> +#include <tqspinbox.h> +#include <tqtimer.h> + +#include <kapplication.h> +#include <kconfig.h> +#include <kglobal.h> +#include <kglobalsettings.h> +#include <kiconloader.h> +#include <klistbox.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kseparator.h> +#include <kpalette.h> +#include <kimageeffect.h> + +#include <kcolordialog.h> +#include <kcolordrag.h> +#include <config.h> +#include <kdebug.h> + +#include <kis_meta_registry.h> +#include <kis_color.h> +#include <kis_factory.h> +#include <kis_colorspace_factory_registry.h> +#include "kis_palette_widget.h" +#include "kis_resource.h" +#include "kis_palette.h" +#include "kis_palette_view.h" + +KisPaletteWidget::KisPaletteWidget( TQWidget *tqparent, int minWidth, int cols) + : TQWidget( tqparent ), mMinWidth(minWidth), mCols(cols) +{ + init = false; + + m_currentPalette = 0; + + TQVBoxLayout *tqlayout = new TQVBoxLayout( this ); + + combo = new TQComboBox( false, this ); + combo->setFocusPolicy( TQ_ClickFocus ); + tqlayout->addWidget(combo); + + m_view = new KisPaletteView(this, 0, minWidth, cols); + tqlayout->addWidget( m_view ); + + //setFixedSize(tqsizeHint()); + + connect(combo, TQT_SIGNAL(activated(const TQString &)), + this, TQT_SLOT(slotSetPalette(const TQString &))); + connect(m_view, TQT_SIGNAL(colorSelected(const KisColor &)), + this, TQT_SIGNAL(colorSelected(const KisColor &))); + connect(m_view, TQT_SIGNAL(colorSelected(const TQColor &)), + this, TQT_SIGNAL(colorSelected(const TQColor &))); + connect(m_view, TQT_SIGNAL(colorDoubleClicked(const KisColor &, const TQString &)), + this, TQT_SIGNAL(colorDoubleClicked(const KisColor &, const TQString &))); +} + +KisPaletteWidget::~KisPaletteWidget() +{ +} + +TQString KisPaletteWidget::palette() const +{ + return combo->currentText(); +} + + +// 2000-02-12 Espen Sand +// Set the color in two steps. The setPalette() slot will not emit a signal +// with the current color setting. The reason is that setPalette() is used +// by the color selector dialog on startup. In the color selector dialog +// we normally want to display a startup color which we specify +// when the dialog is started. The slotSetPalette() slot below will +// set the palette and then use the information to emit a signal with the +// new color setting. It is only used by the combobox widget. +// +void KisPaletteWidget::slotSetPalette( const TQString &_paletteName ) +{ + setPalette( _paletteName ); + m_view->slotColorCellSelected(0); // FIXME: We need to save the current value!! +} + + +void KisPaletteWidget::setPalette( const TQString &_paletteName ) +{ + TQString paletteName( _paletteName); + + m_currentPalette = m_namedPaletteMap[paletteName]; + + if (combo->currentText() != paletteName) + { + bool found = false; + for(int i = 0; i < combo->count(); i++) + { + if (combo->text(i) == paletteName) + { + combo->setCurrentItem(i); + found = true; + break; + } + } + if (!found) + { + combo->insertItem(paletteName); + combo->setCurrentItem(combo->count()-1); + } + } + + m_view->setPalette(m_currentPalette); +} + +void KisPaletteWidget::slotAddPalette(KisResource * palette) +{ + KisPalette * p = dynamic_cast<KisPalette*>(palette); + + m_namedPaletteMap.insert(palette->name(), p); + + combo->insertItem(palette->name()); + + if (!init) { + combo->setCurrentItem(0); + setPalette(combo ->currentText()); + init = true; + } +} + + +#include "kis_palette_widget.moc" + diff --git a/chalk/ui/kis_palette_widget.h b/chalk/ui/kis_palette_widget.h new file mode 100644 index 00000000..6323b0a7 --- /dev/null +++ b/chalk/ui/kis_palette_widget.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __KIS_PALETTE_WIDGET_H__ +#define __KIS_PALETTE_WIDGET_H__ + +#include <tqdict.h> +#include "kis_palette_view.h" + +class TQComboBox; +class TQLineEdit; +class KListBox; +class KisPalette; +class KisResource; +class KisColor; + +/** + * A color palette in table form. + * + * This is copied, mostly, from KPaletteTable in KColorDialog, original + * @author was Waldo Bastian <bastian@kde.org> -- much has changed, though, + * to work with KisPalettes and the resource server. + */ +class KisPaletteWidget : public TQWidget +{ + Q_OBJECT + TQ_OBJECT +public: + KisPaletteWidget( TQWidget *tqparent, int minWidth=210, int cols = 16); + virtual ~KisPaletteWidget(); + + TQString palette() const; + KisPaletteEntry currentEntry() const { return m_view->currentEntry(); } + +public slots: + void setPalette(const TQString &paletteName); + +signals: + void colorSelected(const KisColor &); + void colorSelected(const TQColor&); + void colorDoubleClicked( const KisColor &, const TQString &); + +protected slots: + void slotSetPalette( const TQString &_paletteName ); + +public slots: + // Called by the resource server whenever a palette is loaded. + void slotAddPalette(KisResource * palette); + +protected: + void readNamedColor( void ); + +protected: + KisPaletteView* m_view; + TQDict<KisPalette> m_namedPaletteMap; + KisPalette * m_currentPalette; + TQComboBox *combo; + TQScrollView *sv; + int mMinWidth; + int mCols; + bool init; +}; + +#endif + diff --git a/chalk/ui/kis_part_layer.cc b/chalk/ui/kis_part_layer.cc new file mode 100644 index 00000000..401721b5 --- /dev/null +++ b/chalk/ui/kis_part_layer.cc @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org> + * (c) 2005 Bart Coppens <kde@bartcoppens.be> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "tqpaintdevice.h" +#include "tqpixmap.h" +#include "tqimage.h" +#include "tqpainter.h" + +#include <klocale.h> + +#include "KoDocument.h" +#include "KoDocumentChild.h" +#include "KoFrame.h" +#include "KoView.h" + +#include "kis_layer.h" +#include "kis_types.h" +#include "kis_colorspace_factory_registry.h" +#include "kis_part_layer.h" +#include "kis_group_layer.h" +#include "kis_factory.h" +#include "kis_paint_device.h" +#include <kis_meta_registry.h> + +KisChildDoc::KisChildDoc ( KisDoc * kisDoc, const TQRect & rect, KoDocument * childDoc ) + : KoDocumentChild( kisDoc, childDoc, rect ) + , m_doc(kisDoc) + , m_partLayer(0) +{ +} + + +KisChildDoc::KisChildDoc ( KisDoc * kisDoc ) + : KoDocumentChild( kisDoc) + , m_partLayer(0) +{ +} + +KisChildDoc::~KisChildDoc () +{ + // XXX doesn't this get deleted by itself or by anything else? Certainly looks so + // (otherwise I get a double deletion of a TQObject, and chalk crashes) + //delete m_doc; +} + + +KisPartLayerImpl::KisPartLayerImpl(KisImageSP img, KisChildDoc * doc) + : super(img, i18n("Embedded Document"), OPACITY_OPAQUE), m_doc(doc) +{ + m_cache = new KisPaintDevice( + KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA",""),""), name().latin1() ); + m_activated = false; +} + +KisPartLayerImpl::~KisPartLayerImpl() +{ +} + +KisLayerSP KisPartLayerImpl::clone() const { + return new KisPartLayerImpl(image(), childDoc()); +} + +// Called when the layer is made active +void KisPartLayerImpl::childActivated(KoDocumentChild* child) +{ + // Clear the image, so that if we move the part while activated, no ghosts show up + if (!m_activated && child == m_doc) { + TQRect rect = extent(); + m_activated = true; + setDirty(rect); + TQPtrList<KoView> views = child->tqparentDocument()->views(); + Q_ASSERT(views.count()); + // XXX iterate over views + connect(views.at(0), TQT_SIGNAL(activated(bool)), + this, TQT_SLOT(childDeactivated(bool))); + } +} + +// Called when another layer is made inactive +void KisPartLayerImpl::childDeactivated(bool activated) +{ + // We probably changed, notify the image that it needs to tqrepaint where we currently updated + // We use the original tqgeometry + if (m_activated && !activated /* no clue, but debugging suggests it is false here */) { + TQPtrList<KoView> views = m_doc->tqparentDocument()->views(); + Q_ASSERT(views.count()); + views.at(0)->disconnect(TQT_SIGNAL(activated(bool))); + m_activated = false; + setDirty(m_doc->tqgeometry()); + } +} + +void KisPartLayerImpl::setX(TQ_INT32 x) { + TQRect rect = m_doc->tqgeometry(); + + // KisPaintDevice::move moves to absolute coordinates, not relative. Work around that here, + // since the part is not necesarily started at (0,0) + rect.moveBy(x - this->x(), 0); + m_doc->setGeometry(rect); +} + +void KisPartLayerImpl::setY(TQ_INT32 y) { + TQRect rect = m_doc->tqgeometry(); + + // KisPaintDevice::move moves to absolute coordinates, not relative. Work around that here, + // since the part is not necesarily started at (0,0) + rect.moveBy(0, y - this->y()); + m_doc->setGeometry(rect); +} + +void KisPartLayerImpl::paintSelection(TQImage &img, TQ_INT32 x, TQ_INT32 y, TQ_INT32 w, TQ_INT32 h) { + uchar *j = img.bits(); + TQRect rect = m_doc->tqgeometry(); + + for (int y2 = y; y2 < h + y; ++y2) { + for (int x2 = x; x2 < w + x; ++x2) { + if (!rect.tqcontains(x2, y2)) { + TQ_UINT8 g = (*(j + 0) + *(j + 1 ) + *(j + 2 )) / 9; + *(j+0) = 165+g; + *(j+1) = 128+g; + *(j+2) = 128+g; + } + j+=4; + } + } + +} + +KisPaintDeviceSP KisPartLayerImpl::prepareProjection(KisPaintDeviceSP projection, const TQRect& r) +{ + if (!m_doc || !m_doc->document() || m_activated) return 0; + + m_cache->clear(); + + TQRect intersection(r.intersect(exactBounds())); + if (intersection.isEmpty()) + return m_cache; + // XXX: have a look at the comments and see if they still truthfully represent the code :/ + + // We know the embedded part's size through the ChildDoc + // We move it to (0,0), since that is what we will start painting from in paintEverything. + TQRect embedRect(intersection); + embedRect.moveBy(- exactBounds().x(), - exactBounds().y()); + TQRect paintRect(exactBounds()); + paintRect.moveBy(- exactBounds().x(), - exactBounds().y()); + + TQPixmap pm1(projection->convertToTQImage(0 /*srgb XXX*/, + intersection.x(), intersection.y(), + intersection.width(), intersection.height())); + TQPixmap pm2(extent().width(), extent().height()); + copyBlt(&pm2, embedRect.x(), embedRect.y(), &pm1, + 0, 0, embedRect.width(), embedRect.height()); + TQPainter painter(&pm2); + painter.setClipRect(embedRect); + + // KWord's KWPartFrameSet::drawFrameContents has some interesting remarks concerning + // the semantics of the paintEverything call. + // Since a Chalk Device really is displaysize/zoom agnostic, caring about zoom is not + // really as important here. What we paint at the moment, is just (0,0)x(w,h) + // Paint transparent, no zoom: + m_doc->document()->paintEverything(painter, paintRect, true); + + copyBlt(&pm1, 0, 0, &pm2, + embedRect.x(), embedRect.y(), embedRect.width(), embedRect.height()); + TQImage qimg = pm1.convertToImage(); + + //assume the part is sRGB for now, and that "" is sRGB + // And we need to paint offsetted + m_cache->convertFromTQImage(qimg, "", intersection.left(), intersection.top()); + + return m_cache; +} + +TQImage KisPartLayerImpl::createThumbnail(TQ_INT32 w, TQ_INT32 h) { + TQRect bounds(exactBounds()); + TQPixmap pm(w, h); + TQPainter painter(&pm); + + painter.fillRect(0, 0, w, h, TQt::white); + + painter.scale(w / bounds.width(), h / bounds.height()); + m_doc->document()->paintEverything(painter, bounds); + TQImage qimg = pm.convertToImage(); + + return qimg; +} + +bool KisPartLayerImpl::saveToXML(TQDomDocument doc, TQDomElement elem) +{ + TQDomElement embeddedElement = doc.createElement("layer"); + embeddedElement.setAttribute("name", name()); + + // x and y are loaded from the rect element in the embedded object tag + embeddedElement.setAttribute("x", 0); + embeddedElement.setAttribute("y", 0); + + embeddedElement.setAttribute("opacity", opacity()); + embeddedElement.setAttribute("compositeop", compositeOp().id().id()); + embeddedElement.setAttribute("visible", visible()); + embeddedElement.setAttribute("locked", locked()); + embeddedElement.setAttribute("layertype", "partlayer"); + elem.appendChild(embeddedElement); + + TQDomElement objectElem = childDoc()->save(doc); + embeddedElement.appendChild(objectElem); + + return true; +} + +KisConnectPartLayerVisitor::KisConnectPartLayerVisitor(KisImageSP img, KisView* view, bool mode) + : m_img(img), m_view(view), m_connect(mode) +{ +} + +bool KisConnectPartLayerVisitor::visit(KisGroupLayer *layer) { + KisLayerSP child = layer->lastChild(); + + while (child) { + child->accept(*this); + child = child->prevSibling(); + } + + return true; +} + +bool KisConnectPartLayerVisitor::visit(KisPartLayer *layer) { + if (m_connect) { + TQObject::connect(m_view, TQT_SIGNAL(childActivated(KoDocumentChild*)), + layer, TQT_SLOT(childActivated(KoDocumentChild*))); + } else { + TQObject::disconnect(m_view, TQT_SIGNAL(childActivated(KoDocumentChild*)), layer, 0 ); + } + + return true; +} + +bool KisConnectPartLayerVisitor::visit(KisPaintLayer*) { + return true; +} + +bool KisConnectPartLayerVisitor::visit(KisAdjustmentLayer*) { + return true; +} + +#include "kis_part_layer.moc" diff --git a/chalk/ui/kis_part_layer.h b/chalk/ui/kis_part_layer.h new file mode 100644 index 00000000..65026139 --- /dev/null +++ b/chalk/ui/kis_part_layer.h @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef _KIS_PART_LAYER_ +#define _KIS_PART_LAYER_ + +#include <tqrect.h> + +#include <KoDocument.h> +#include <KoDocumentChild.h> + +#include "kis_paint_layer.h" +#include "kis_types.h" +#include "kis_doc.h" +#include "kis_part_layer_iface.h" +#include "kis_view.h" +#include "kis_layer_visitor.h" + +class KoFrame; +class KoDocument; + + +/** + * The child document is responsible for saving and loading the embedded layers. + */ +class KisChildDoc : public KoDocumentChild +{ + +public: + KisChildDoc ( KisDoc * kisDoc, const TQRect& rect, KoDocument * childDoc ); + KisChildDoc ( KisDoc * kisDdoc ); + + virtual ~KisChildDoc(); + + KisDoc * tqparent() const { return m_doc; } + + void setPartLayer (KisPartLayerSP layer) { m_partLayer = layer; } + + KisPartLayerSP partLayer() const { return m_partLayer; } +protected: + + KisDoc * m_doc; + KisPartLayerSP m_partLayer; +}; + + +/** + * A PartLayer is a layer that contains a KOffice Part like a KWord document + * or a KSpread spreadsheet. Or whatever. A Karbon drawing. + * + * The part is rendered into an RBGA8 paint device so we can composite it with + * the other layers. + * + * When it is activated (see activate()), it draws a rectangle around itself on the kisdoc, + * whereas when it is deactivated (deactivate()), it removes that rectangle and commits + * the child to the paint device. + * + * Embedded parts should get loaded and saved to the Native Chalk Fileformat natively. + */ +class KisPartLayerImpl : public KisPartLayer { + Q_OBJECT + TQ_OBJECT + typedef KisPartLayer super; +public: + KisPartLayerImpl(KisImageSP img, KisChildDoc * doc); + virtual ~KisPartLayerImpl(); + + virtual KisLayerSP clone() const; + + /// Called when the layer is made active + virtual void activate() {} + + /// Called when another layer is made inactive + virtual void deactivate() {} + + /// Returns the childDoc so that we can access the doc from other places, if need be (KisDoc) + virtual KisChildDoc* childDoc() const { return m_doc; } + + void setDocType(const TQString& type) { m_docType = type; } + TQString docType() const { return m_docType; } + + virtual void setX(TQ_INT32 x); + virtual void setY(TQ_INT32 y); + virtual TQ_INT32 x() const { return m_doc->tqgeometry() . x(); } + virtual TQ_INT32 y() const { return m_doc->tqgeometry() . y(); } //m_paintLayer->y(); } + virtual TQRect extent() const { return m_doc->tqgeometry(); } + virtual TQRect exactBounds() const { return m_doc->tqgeometry(); } + + virtual TQImage createThumbnail(TQ_INT32 w, TQ_INT32 h); + + virtual bool accept(KisLayerVisitor& visitor) { + return visitor.visit(this); + } + + virtual KisPaintDeviceSP prepareProjection(KisPaintDeviceSP projection, const TQRect& r); + + virtual void paintSelection(TQImage &img, TQ_INT32 x, TQ_INT32 y, TQ_INT32 w, TQ_INT32 h); + + virtual bool saveToXML(TQDomDocument doc, TQDomElement elem); +private slots: + /// Repaints our device with the data from the embedded part + //void tqrepaint(); + /// When we activate the embedding, we clear ourselves + void childActivated(KoDocumentChild* child); + void childDeactivated(bool activated); + + +private: + // KisPaintLayerSP m_paintLayer; + KisPaintDeviceSP m_cache; + KoFrame * m_frame; // The widget that holds the editable view of the embedded part + KisChildDoc * m_doc; // The sub-document + TQString m_docType; + bool m_activated; +}; + +/** + * Visitor that connects all partlayers in an image to a KisView's signals + */ +class KisConnectPartLayerVisitor : public KisLayerVisitor { + KisImageSP m_img; + KisView* m_view; + bool m_connect; // connects, or disconnects signals +public: + KisConnectPartLayerVisitor(KisImageSP img, KisView* view, bool mode); + virtual ~KisConnectPartLayerVisitor() {} + + virtual bool visit(KisPaintLayer *layer); + virtual bool visit(KisGroupLayer *layer); + virtual bool visit(KisPartLayer *layer); + virtual bool visit(KisAdjustmentLayer *layer); +}; + +#endif // _KIS_PART_LAYER_ diff --git a/chalk/ui/kis_part_layer_handler.cc b/chalk/ui/kis_part_layer_handler.cc new file mode 100644 index 00000000..f062e4a1 --- /dev/null +++ b/chalk/ui/kis_part_layer_handler.cc @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2006 Bart Coppens <kde@bartcoppens.be> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_canvas.h" +#include <fixx11h.h> // kis_canvas.h does X11 stuff + +#include <tqpainter.h> +#include <tqcursor.h> + +#include "kis_cursor.h" +#include "kis_canvas_painter.h" +#include "kis_move_event.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_group_layer.h" +#include "kis_part_layer_handler.h" + +KisPartLayerHandler::KisPartLayerHandler(KisView* view, const KoDocumentEntry& entry, + KisGroupLayerSP tqparent, KisLayerSP above) + : m_parent(tqparent), m_above(above), m_view(view), m_entry(entry) { + m_started = false; + view->getCanvasController()->setCanvasCursor( KisCursor::selectCursor() ); +} + +void KisPartLayerHandler::done() { + emit handlerDone(); // We will get deleted by the view +} + +void KisPartLayerHandler::gotMoveEvent(KisMoveEvent* event) { + if (!m_started) { + emit sigGotMoveEvent(event); + return; + } + + KisCanvasPainter painter(m_view->getCanvasController()->kiscanvas()); + painter.setRasterOp( NotROP ); + + // erase old lines + TQRect r(m_start, m_end); + r = r.normalize(); + if (!r.isEmpty()) + painter.drawRect(r); + + m_end = event->pos().roundTQPoint(); + r = TQRect(m_start, m_end).normalize(); + + painter.drawRect(r); + painter.end(); +} + +void KisPartLayerHandler::gotButtonPressEvent(KisButtonPressEvent* event) { + m_start = event->pos().roundTQPoint(); + m_end = m_start; + m_started = true; +} + +void KisPartLayerHandler::gotButtonReleaseEvent(KisButtonReleaseEvent* event) { + if (!m_started) { + done(); + return; + } + + m_end = event->pos().roundTQPoint(); + + TQRect r(m_start, m_end); + + m_view->insertPart(r.normalize(), m_entry, m_parent, m_above); + // We will get deleted by the view through the above +} + +void KisPartLayerHandler::gotKeyPressEvent(TQKeyEvent* event) { + if (event->key() == Key_Escape) { + done(); + } else { + emit sigGotKeyPressEvent(event); + } +} + +#include "kis_part_layer_handler.moc" diff --git a/chalk/ui/kis_part_layer_handler.h b/chalk/ui/kis_part_layer_handler.h new file mode 100644 index 00000000..746b23d9 --- /dev/null +++ b/chalk/ui/kis_part_layer_handler.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2006 Bart Coppens <kde@bartcoppens.be> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_PART_LAYER_HANDLER_ +#define KIS_PART_LAYER_HANDLER_ + +#include <tqobject.h> +#include <KoQueryTrader.h> // KoDocumentEntry + +#include "kis_types.h" +#include "kis_doc.h" +#include "kis_view.h" + +class TQKeyEvent; + +class KisPartLayerHandler : public TQObject { +Q_OBJECT + TQ_OBJECT +public: + KisPartLayerHandler(KisView* view, const KoDocumentEntry& entry, + KisGroupLayerSP tqparent, KisLayerSP above); +signals: + void sigGotMoveEvent(KisMoveEvent* event); + void sigGotKeyPressEvent(TQKeyEvent* event); + void handlerDone(); + +protected slots: + + void gotMoveEvent(KisMoveEvent* event); + void gotButtonPressEvent(KisButtonPressEvent* event); + void gotButtonReleaseEvent(KisButtonReleaseEvent* event); + void gotKeyPressEvent(TQKeyEvent* event); +protected: + void done(); + KisGroupLayerSP m_parent; + KisLayerSP m_above; + KisView* m_view; + KoDocumentEntry m_entry; + TQPoint m_start; + TQPoint m_end; + bool m_started; +}; + +#endif // KIS_PART_LAYER_HANDLER diff --git a/chalk/ui/kis_pattern_chooser.cc b/chalk/ui/kis_pattern_chooser.cc new file mode 100644 index 00000000..f19200bf --- /dev/null +++ b/chalk/ui/kis_pattern_chooser.cc @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2004 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include <tqlabel.h> +#include <tqlayout.h> +#include <klocale.h> +#include <koIconChooser.h> + +#include "kis_colorspace.h" +#include "kis_pattern_chooser.h" +#include "kis_global.h" +#include "kis_icon_item.h" +#include "kis_pattern.h" + +KisPatternChooser::KisPatternChooser(TQWidget *tqparent, const char *name) : super(tqparent, name) +{ + m_lbName = new TQLabel(this); + + TQVBoxLayout *mainLayout = new TQVBoxLayout(this, 2, -1, "main tqlayout"); + + mainLayout->addWidget(m_lbName); + mainLayout->addWidget(chooserWidget(), 10); +} + +KisPatternChooser::~KisPatternChooser() +{ +} + +void KisPatternChooser::update(KoIconItem *item) +{ + KisIconItem *kisItem = static_cast<KisIconItem *>(item); + + if (item) { + KisPattern *pattern = static_cast<KisPattern *>(kisItem->resource()); + + TQString text = TQString("%1 (%2 x %3)").tqarg(pattern->name()).tqarg(pattern->width()).tqarg(pattern->height()); + + m_lbName->setText(text); + } +} + +#include "kis_pattern_chooser.moc" + diff --git a/chalk/ui/kis_pattern_chooser.h b/chalk/ui/kis_pattern_chooser.h new file mode 100644 index 00000000..b7a61080 --- /dev/null +++ b/chalk/ui/kis_pattern_chooser.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2004 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_PATTERN_CHOOSER_H_ +#define KIS_PATTERN_CHOOSER_H_ + +#include "kis_itemchooser.h" + +class TQLabel; + +class KisPatternChooser : public KisItemChooser { + typedef KisItemChooser super; + Q_OBJECT + TQ_OBJECT + +public: + KisPatternChooser(TQWidget *tqparent = 0, const char *name = 0); + virtual ~KisPatternChooser(); + +protected: + virtual void update(KoIconItem *item); + +private: + TQLabel *m_lbName; +}; + +#endif // KIS_PATTERN_CHOOSER_H_ + diff --git a/chalk/ui/kis_perspective_grid_manager.cpp b/chalk/ui/kis_perspective_grid_manager.cpp new file mode 100644 index 00000000..c454af80 --- /dev/null +++ b/chalk/ui/kis_perspective_grid_manager.cpp @@ -0,0 +1,159 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_perspective_grid_manager.h" + +#include <kaction.h> +#include <klocale.h> +#include <kmessagebox.h> + +#include "kis_image.h" +#include "kis_grid_drawer.h" +#include "kis_perspective_grid.h" +#include "kis_view.h" + +KisPerspectiveGridManager::KisPerspectiveGridManager(KisView * tqparent) + : TQObject() + , m_toggleEdition(false) + , m_view(tqparent) +{ + +} + + +KisPerspectiveGridManager::~KisPerspectiveGridManager() +{ + +} + +void KisPerspectiveGridManager::updateGUI() +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + + + if (image ) { + KisPerspectiveGrid* pGrid = image->perspectiveGrid(); + m_toggleGrid->setEnabled( pGrid->hasSubGrids()); + } +} + +void KisPerspectiveGridManager::setup(KActionCollection * collection) +{ + kdDebug() << "KisPerspectiveGridManager::setup(KActionCollection * collection)" << endl; + m_toggleGrid = new KToggleAction(i18n("Show Perspective Grid"), "", this, TQT_SLOT(toggleGrid()), collection, "view_toggle_perspective_grid"); + m_toggleGrid->setCheckedState(KGuiItem(i18n("Hide Perspective Grid"))); + m_toggleGrid->setChecked(false); + m_gridClear = new KAction(i18n("Clear Perspective Grid"), 0, "", this, TQT_SLOT(clearPerspectiveGrid()), collection, "view_clear_perspective_grid"); +} + +void KisPerspectiveGridManager::setGridVisible(bool t) +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + + + if (t && image ) { + KisPerspectiveGrid* pGrid = image->perspectiveGrid(); + if( pGrid->hasSubGrids()) + { + m_toggleGrid->setChecked(true); + } + } else { + m_toggleGrid->setChecked(false); + } + m_view->refreshKisCanvas(); +} + + +void KisPerspectiveGridManager::toggleGrid() +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + + + if (image && m_toggleGrid->isChecked()) { + KisPerspectiveGrid* pGrid = image->perspectiveGrid(); + + if(!pGrid->hasSubGrids()) + { + KMessageBox::error(0, i18n("Before displaying the perspective grid, you need to initialize it with the perspective grid tool"), i18n("No Perspective Grid to Display") ); + m_toggleGrid->setChecked(false); + } + } + m_view->updateCanvas(); +} + +void KisPerspectiveGridManager::clearPerspectiveGrid() +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + if (image ) { + image->perspectiveGrid()->clearSubGrids(); + m_view->updateCanvas(); + m_toggleGrid->setChecked(false); + m_toggleGrid->setEnabled(false); + } +} + +void KisPerspectiveGridManager::startEdition() +{ + m_toggleEdition = true; + m_toggleGrid->setEnabled( false ); + if( m_toggleGrid->isChecked() ) + m_view->updateCanvas(); +} + +void KisPerspectiveGridManager::stopEdition() +{ + m_toggleEdition = false; + m_toggleGrid->setEnabled( true ); + if( m_toggleGrid->isChecked() ) + m_view->updateCanvas(); +} + +void KisPerspectiveGridManager::drawGrid(TQRect wr, TQPainter *p, bool openGL ) +{ + KisImageSP image = m_view->canvasSubject()->currentImg(); + + + if (image && m_toggleGrid->isChecked() && !m_toggleEdition) { + KisPerspectiveGrid* pGrid = image->perspectiveGrid(); + + GridDrawer *gridDrawer = 0; + + if (openGL) { + gridDrawer = new OpenGLGridDrawer(); + } else { + Q_ASSERT(p); + + if (p) { + gridDrawer = new TQPainterGridDrawer(p); + } + } + + Q_ASSERT(gridDrawer != 0); + + for( TQValueList<KisSubPerspectiveGrid*>::const_iterator it = pGrid->begin(); it != pGrid->end(); ++it) + { + gridDrawer->drawPerspectiveGrid(image, wr, *it ); + } + delete gridDrawer; + } +} + + +#include "kis_perspective_grid_manager.moc" diff --git a/chalk/ui/kis_perspective_grid_manager.h b/chalk/ui/kis_perspective_grid_manager.h new file mode 100644 index 00000000..85954ba4 --- /dev/null +++ b/chalk/ui/kis_perspective_grid_manager.h @@ -0,0 +1,55 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_PERSPECTIVE_GRID_MANAGER_H +#define KIS_PERSPECTIVE_GRID_MANAGER_H + +#include <tqobject.h> + +class KAction; +class KActionCollection; +class KToggleAction; +class KisView; + +class KisPerspectiveGridManager : public TQObject +{ + Q_OBJECT + TQ_OBJECT + public: + KisPerspectiveGridManager(KisView * tqparent); + ~KisPerspectiveGridManager(); + void setup(KActionCollection * collection); + void drawGrid(TQRect wr, TQPainter *p, bool openGL = false); + void startEdition(); + void stopEdition(); + void setGridVisible(bool t); + public slots: + void updateGUI(); + void clearPerspectiveGrid(); + private slots: + void toggleGrid(); + private: + bool m_toggleEdition; + KisView* m_view; + KToggleAction* m_toggleGrid; + KAction* m_gridClear; +}; + +#endif diff --git a/chalk/ui/kis_populate_visitor.h b/chalk/ui/kis_populate_visitor.h new file mode 100644 index 00000000..d228137a --- /dev/null +++ b/chalk/ui/kis_populate_visitor.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2005 Gábor Lehel <illissius@gmail.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_POPULATE_VISITOR_H +#define KIS_POPULATE_VISITOR_H + +#include <kiconloader.h> +#include "kis_types.h" +#include "kis_layer.h" +#include "kis_group_layer.h" +#include "kis_paint_layer.h" +#include "kis_part_layer.h" +#include "kis_adjustment_layer.h" +#include "kis_layerlist.h" + + +/** + * This visitor walks over the layer tree to fill + * the layer box. + */ +class KisPopulateVisitor: public KisLayerVisitor +{ + public: + KisPopulateVisitor(KisLayerList* widget) + : m_widget(widget) + , m_parent(0) + { } + + KisPopulateVisitor(KisLayerItem* tqparent) + : m_widget(tqparent->listView()) + , m_parent(tqparent) + { } + + virtual bool visit(KisPaintLayer* layer) + { + if (!layer->temporary()) + add(layer); + return true; + } + + virtual bool visit(KisPartLayer* layer) + { + add(layer)->setPixmap(0, SmallIcon("gear", 16)); + return true; + } + + virtual bool visit(KisAdjustmentLayer* layer) + { + add(layer)->setPixmap(0, SmallIcon("tool_filter", 16)); + return true; + } + + virtual bool visit(KisGroupLayer* layer) + { + KisLayerItem* item = add(layer); + item->makeFolder(); + KisPopulateVisitor visitor(item); + for (KisLayerSP l = layer->firstChild(); l; l = l->nextSibling()) + l->accept(visitor); + + vKisLayerSP childLayersAdded = visitor.layersAdded(); + + for (vKisLayerSP::iterator it = childLayersAdded.begin(); it != childLayersAdded.end(); ++it) { + m_layersAdded.append(*it); + } + + return true; + } + + vKisLayerSP layersAdded() const + { + return m_layersAdded; + } + + private: + LayerList* m_widget; + KisLayerItem* m_parent; + vKisLayerSP m_layersAdded; + + KisLayerItem* add(KisLayer* layer) + { + if (!layer) return 0; + + KisImageSP img = layer->image(); + if (!img) return 0; + + KisLayerItem *item; + if (m_parent) { + item = new KisLayerItem(m_parent, layer); + } + else { + item = new KisLayerItem(m_widget, layer); + } + if (layer == img->activeLayer()) { + item->setActive(); + } + m_layersAdded.append(layer); + return item; + } +}; + +#endif diff --git a/chalk/ui/kis_previewdialog.cc b/chalk/ui/kis_previewdialog.cc new file mode 100644 index 00000000..fdeb872a --- /dev/null +++ b/chalk/ui/kis_previewdialog.cc @@ -0,0 +1,46 @@ +/* + * kis_previewdialog.cc - part of Chalk + * + * Copyright (c) 2005 Sven Langkamp <longamp@reallygood.de> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include <tqframe.h> +#include <tqhbox.h> +#include <tqgroupbox.h> +#include <tqlayout.h> + +#include "kis_previewwidget.h" +#include "kis_previewdialog.h" + +KisPreviewDialog::KisPreviewDialog( TQWidget * tqparent, const char * name, bool modal, const TQString &caption) + : super (tqparent, name, modal, caption, Ok | Cancel, Ok) +{ + TQHBox* tqlayout = new TQHBox(this); + tqlayout->setSpacing( 6 ); + + m_containerFrame = new TQFrame( tqlayout, "container" ); + + m_preview = new KisPreviewWidget( tqlayout, "previewWidget" ); + + setMainWidget(tqlayout); +} + +KisPreviewDialog::~KisPreviewDialog() +{ + +} + +#include "kis_previewdialog.moc" diff --git a/chalk/ui/kis_previewdialog.h b/chalk/ui/kis_previewdialog.h new file mode 100644 index 00000000..9f268d44 --- /dev/null +++ b/chalk/ui/kis_previewdialog.h @@ -0,0 +1,45 @@ +/* + * kis_previewdialog.h -- part of Chalk + * + * Copyright (c) 2005 Sven Langkamp <longamp@reallygood.de> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#ifndef KIS_PREVIEWDIALOG_H +#define KIS_PREVIEWDIALOG_H + +#include <kdialogbase.h> + +class KisPreviewWidget; +class TQFrame; + +class KisPreviewDialog: public KDialogBase { + typedef KDialogBase super; + Q_OBJECT + TQ_OBJECT + +public: + KisPreviewDialog( TQWidget* tqparent = 0, const char* name = 0, bool modal = false, const TQString &caption=TQString()); + ~KisPreviewDialog(); + + KisPreviewWidget* previewWidget() { return m_preview; } + TQFrame* container() { return m_containerFrame; } +private: + KisPreviewWidget* m_preview; + TQFrame* m_containerFrame; +}; + +#endif diff --git a/chalk/ui/kis_previewwidget.cc b/chalk/ui/kis_previewwidget.cc new file mode 100644 index 00000000..c9c2a766 --- /dev/null +++ b/chalk/ui/kis_previewwidget.cc @@ -0,0 +1,409 @@ +/* + * kis_previewwidget.cc - part of Chalk + * + * Copyright (c) 2001 John Califf <jwcaliff@compuzone.net> + * Copyright (c) 2004 Bart Coppens <kde@bartcoppens.be> + * Copyright (c) 2005 Cyrille Berger <cberger@cberger.net> + * Copyright (c) 2007 Ben Schleimer <bensch128@yahoo.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <tqcheckbox.h> +#include <tqradiobutton.h> +#include <tqpainter.h> +#include <tqpoint.h> +#include <tqpushbutton.h> +#include <tqlayout.h> +#include <tqlabel.h> +#include <tqapplication.h> +#include <tqcolor.h> +#include <tqgroupbox.h> +#include <tqcursor.h> +#include <tqtimer.h> + +#include <kdebug.h> +#include <kiconloader.h> +#include <kpushbutton.h> + +#include <kis_cursor.h> +#include <kis_colorspace.h> +#include <kis_colorspace_factory_registry.h> +#include <kis_config.h> +#include <kis_filter_strategy.h> +#include <kis_global.h> +#include <kis_image.h> +#include <kis_layer.h> +#include <kis_paint_layer.h> +#include <kis_group_layer.h> +#include <kis_meta_registry.h> +#include <kis_painter.h> +#include <kis_profile.h> +#include <kis_types.h> +#include <kis_undo_adapter.h> +#include <kis_label_progress.h> +#include <kis_selection.h> +#include <kis_transform_worker.h> + +#include "kis_previewwidgetbase.h" +#include "kis_previewwidget.h" +#include "imageviewer.h" + +static const int ZOOM_PAUSE = 100; +static const int FILTER_PAUSE = 500; +static const double ZOOM_FACTOR = 1.1; + +KisPreviewWidget::KisPreviewWidget( TQWidget* tqparent, const char* name ) + : PreviewWidgetBase( tqparent, name ) + , m_autoupdate(true) + , m_previewIsDisplayed(true) + , m_scaledOriginal() + , m_dirtyOriginal(true) + , m_origDevice(new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()->getRGB8(), "temp")) + , m_scaledPreview() + , m_dirtyPreview(true) + , m_previewDevice(new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()->getRGB8(), "temp")) + , m_scaledImage(NULL) + , m_filterZoom(1.0) + , m_zoom(-1.0) + , m_profile(NULL) + , m_progress( 0 ) + , m_zoomTimer(new TQTimer(this)) + , m_filterTimer(new TQTimer(this)) + , m_firstFilter(true) + , m_firstZoom(true) +{ + btnZoomIn->setIconSet(KGlobal::instance()->iconLoader()->loadIconSet( "viewmag+", KIcon::MainToolbar, 16 )); + connect(btnZoomIn, TQT_SIGNAL(clicked()), this, TQT_SLOT(zoomIn())); + btnZoomOut->setIconSet(KGlobal::instance()->iconLoader()->loadIconSet( "viewmag-", KIcon::MainToolbar, 16 )); + connect(btnZoomOut, TQT_SIGNAL(clicked()), this, TQT_SLOT(zoomOut())); + btnUpdate->setIconSet(KGlobal::instance()->iconLoader()->loadIconSet( "reload", KIcon::MainToolbar, 16 )); + connect(btnUpdate, TQT_SIGNAL(clicked()), this, TQT_SLOT(forceUpdate())); + + connect(radioBtnPreview, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(setPreviewDisplayed(bool))); + + connect(checkBoxAutoUpdate, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotSetAutoUpdate(bool))); + btnZoomOneToOne->setIconSet(KGlobal::instance()->iconLoader()->loadIconSet( "viewmag1", KIcon::MainToolbar, 16 )); + connect(btnZoomOneToOne, TQT_SIGNAL(clicked()), this, TQT_SLOT(zoomOneToOne())); + + m_progress = new KisLabelProgress(frmProgress); + m_progress->setMaximumHeight(fontMetrics().height() ); + TQVBoxLayout *vbox = new TQVBoxLayout( frmProgress ); + vbox->addWidget(m_progress); + m_progress->hide(); + + connect(m_zoomTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(updateZoom())); + connect(m_filterTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(runFilterHelper())); + +/* kToolBar1->insertLineSeparator(); + kToolBar1->insertButton("reload",2, true, i18n("Update")); + connect(kToolBar1->getButton(2),TQT_SIGNAL(clicked()),this,TQT_SLOT(forceUpdate())); + + kToolBar1->insertButton("",3, true, i18n("Auto Update")); + connect(kToolBar1->getButton(3),TQT_SIGNAL(clicked()),this,TQT_SLOT(toggleAutoUpdate())); + + kToolBar1->insertButton("",4, true, i18n("Switch")); + connect(kToolBar1->getButton(4),TQT_SIGNAL(clicked()),this,TQT_SLOT(toggleImageDisplayed()));*/ +// these currently don't yet work, reenable when they do work :) (TZ-12-2005) +// TODO reenable these +// kToolBar1->insertButton("",5, true, i18n("Popup Original and Preview")); +} + +KisPreviewWidget::~KisPreviewWidget() { } + +void KisPreviewWidget::forceUpdate() +{ + if(m_previewIsDisplayed) + { + m_groupBox->setTitle(m_origDevice->name()); + emit updated(); + } +} + +void KisPreviewWidget::slotSetDevice(KisPaintDeviceSP dev) +{ + Q_ASSERT( dev ); + + if (!dev) return; + + m_origDevice = dev; + m_previewDevice = dev; + m_filterZoom = 1.0; + + KisConfig cfg; + TQString monitorProfileName = cfg.monitorProfile(); + m_profile = KisMetaRegistry::instance()->csRegistry()->getProfileByName(monitorProfileName); + + TQRect r = dev->exactBounds(); + + m_groupBox->setTitle(i18n("Preview: ") + dev->name()); + m_previewIsDisplayed = true; + + m_zoom = -1.0; + zoomChanged(double(m_preview->width()) / double(r.width()) ); +} + +void KisPreviewWidget::updateZoom() +{ + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + + if(m_previewIsDisplayed) + { + if(m_dirtyPreview) + { + TQSize r = m_previewDevice->extent().size(); + int w = r.width(), h = r.height(); + int sw = int(ceil(m_zoom * w / m_filterZoom)); + int sh = int(ceil(m_zoom * h / m_filterZoom)); + m_dirtyPreview = false; + m_scaledPreview = m_previewDevice->convertToTQImage(m_profile, 0, 0, w, h); + m_scaledPreview = m_scaledPreview.scale(sw,sh, TQ_ScaleMax); // Use scale instead of smoothScale for speed up + } + m_preview->setImage(m_scaledPreview); + } else + { + if(m_dirtyOriginal) + { + TQSize r = m_origDevice->extent().size(); + int w = r.width(), h = r.height(); + int sw = int(ceil(m_zoom * w)); + int sh = int(ceil(m_zoom * h)); + m_dirtyOriginal = false; + m_scaledOriginal = m_origDevice->convertToTQImage(m_profile, 0, 0, w, h); + m_scaledOriginal = m_scaledOriginal.scale(sw,sh, TQ_ScaleMax); // Use scale instead of smoothScale for speed up + } + m_preview->setImage(m_scaledOriginal); + } + + TQApplication::restoreOverrideCursor(); +} + +void KisPreviewWidget::slotSetAutoUpdate(bool set) { + m_autoupdate = set; +} + +void KisPreviewWidget::wheelEvent(TQWheelEvent * e) +{ + if (e->delta() > 0) { + zoomIn(); + } else { + zoomOut(); + } + e->accept(); +} + +void KisPreviewWidget::setPreviewDisplayed(bool v) +{ + if(v != m_previewIsDisplayed) + { + m_previewIsDisplayed = v; + if(m_previewIsDisplayed) { + m_groupBox->setTitle(i18n("Preview: ") + m_origDevice->name()); + } else { + m_groupBox->setTitle(i18n("Original: ") + m_origDevice->name()); + } + // Call directly without any pause because there is no scaling + updateZoom(); + } +} + +void KisPreviewWidget::needUpdate() +{ + if(m_previewIsDisplayed) + m_groupBox->setTitle(i18n("Preview (needs update)")); +} + +bool KisPreviewWidget::getAutoUpdate() const { + return m_autoupdate; +} + +void KisPreviewWidget::zoomChanged(const double zoom) +{ + // constrain the zoom + double tZoom = zoom; + if(zoom <= 1./8.) { tZoom = 1./8.; } + if(zoom > 8.) { tZoom = 8.; } + + if(tZoom != m_zoom) + { + m_zoom = tZoom; + m_dirtyOriginal = true; + m_dirtyPreview = true; + + if(m_firstZoom) { + m_firstZoom = false; + updateZoom(); + } else { + m_zoomTimer->start(ZOOM_PAUSE, true); + } + } +} + +void KisPreviewWidget::zoomIn() { + zoomChanged(m_zoom * ZOOM_FACTOR); +} + +void KisPreviewWidget::zoomOut() { + zoomChanged(m_zoom / ZOOM_FACTOR); +} + +void KisPreviewWidget::zoomOneToOne() { + zoomChanged(1.0); +} + +static inline void cropDevice(KisPaintDevice * device, const double & zoom) { + TQRect r = device->exactBounds(); + r.setX(int(zoom * r.x()) ); + r.setY(int(zoom * r.y()) ); + r.setWidth(int(zoom * r.width()) ); + r.setHeight(int(zoom * r.height()) ); + device->crop(r); +} + +class MyCropVisitor : public KisLayerVisitor { + const double m_zoom; + +public: + MyCropVisitor(const double & z) : m_zoom(z) { } + virtual ~MyCropVisitor() { } + + virtual bool visit(KisPaintLayer *layer) { + KisPaintDeviceSP device = layer->paintDevice(); + ::cropDevice(device.data(), m_zoom); + // Make sure we have a tight fit for the selection + if(device->hasSelection()) { + ::cropDevice(device->selection().data(), m_zoom); + } + + return true; + } + virtual bool visit(KisGroupLayer *layer) { + for(KisLayerSP l = layer->firstChild(); l; l = l->nextSibling()) { + l->accept(*this); + } + return true; + } + virtual bool visit(KisPartLayer *) { return true; } + virtual bool visit(KisAdjustmentLayer *) { return true; } +}; + +void KisPreviewWidget::runFilter(KisFilter * filter, KisFilterConfiguration * config) { + if(!filter) return; + if(!config) return; + + m_filter = filter; + m_config = config; + + if(m_firstFilter) { + m_firstFilter = false; + runFilterHelper(); + } else { + m_filterTimer->start(FILTER_PAUSE, true); + } +} + +/** + * XXX: Fix the situations which m_origDevice is NOT associated with a image. + * If it comes from a adjustment layer or projection or thumbnail. Currently, nothing happens + */ +void KisPreviewWidget::runFilterHelper() { + + m_filterZoom = m_zoom; + // Dont scale more then 1.0 so we don't waste time in preview widget for large scaling. + if(m_filterZoom > 1.0) { + m_filterZoom = 1.0; + } + + KisPaintDeviceSP scaledDevice; + KisHermiteFilterStrategy strategy; + + // Copy the image and scale + if (m_origDevice->image()) + { + m_scaledImage = new KisImage(*m_origDevice->image()); + if(!m_origDevice->tqparentLayer()) return; + TQString layerName = m_origDevice->tqparentLayer()->name(); + KisPaintLayerSP pl = ::tqqt_cast<KisPaintLayer*>(m_scaledImage->findLayer(layerName)); + if(!pl) return; + scaledDevice = pl->paintDevice(); + + KisSelectionSP select; + if(scaledDevice->hasSelection()) + { + select = new KisSelection(*scaledDevice->selection()); + scaledDevice->deselect(); + } + // Scale + m_scaledImage->setUndoAdapter(NULL); + m_scaledImage->scale(m_filterZoom, m_filterZoom, NULL, &strategy); + // Scale the selection + if(select) + { + KisPaintDeviceSP t = select.data(); + KisTransformWorker tw(t, m_filterZoom, m_filterZoom, + 0.0, 0.0, 0.0, 0, 0, NULL, &strategy); + tw.run(); + scaledDevice->setSelection(select); + select->setParentLayer(scaledDevice->tqparentLayer()); + } + + // Crop by the zoom value instead of cropping by rectangle. It gives better results + MyCropVisitor v(m_filterZoom); + m_scaledImage->rootLayer()->accept(v); + } else + { + scaledDevice = new KisPaintDevice(*m_origDevice); + KisSelectionSP select; + if(scaledDevice->hasSelection()) + { + select = new KisSelection(*scaledDevice->selection()); + scaledDevice->deselect(); + } + KisTransformWorker tw(scaledDevice, m_filterZoom, m_filterZoom, + 0.0, 0.0, 0.0, 0, 0, NULL, &strategy); + tw.run(); + // Scale the selection + if(select) + { + KisPaintDeviceSP t = select.data(); + KisTransformWorker tw(t, m_filterZoom, m_filterZoom, + 0.0, 0.0, 0.0, 0, 0, NULL, &strategy); + tw.run(); + scaledDevice->setSelection(select); + ::cropDevice(select.data(), m_filterZoom); + } + ::cropDevice(scaledDevice.data(), m_filterZoom); + } + + m_previewDevice = new KisPaintDevice(*scaledDevice); + + // Setup the progress display + m_filter->enableProgress(); + m_progress->setSubject(m_filter, true, true); + m_filter->setProgressDisplay(m_progress); + m_filter->process(scaledDevice, m_previewDevice, m_config, scaledDevice->exactBounds()); + m_filter->disableProgress(); + + m_dirtyPreview = true; + + if(m_firstZoom) { + m_firstZoom = false; + updateZoom(); + } else { + m_zoomTimer->start(ZOOM_PAUSE, true); + } +} + +#include "kis_previewwidget.moc" diff --git a/chalk/ui/kis_previewwidget.h b/chalk/ui/kis_previewwidget.h new file mode 100644 index 00000000..bcdf437e --- /dev/null +++ b/chalk/ui/kis_previewwidget.h @@ -0,0 +1,141 @@ +/* + * kis_previewwidget.h - part of Chalk + * + * Copyright (c) 2001 John Califf <jcaliff@compuzone.net> + * Copyright (c) 2004 Bart Coppens <kde@bartcoppens.be> + * Copyright (c) 2005 Cyrille Berger <cberger@cberger.net> + * Copyright (c) 2007 Benjamin Schleimer <bensch128@yahoo.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef __kis_previewwidget_h__ +#define __kis_previewwidget_h__ + +#include <tqimage.h> +#include <tqevent.h> + +#include "kis_types.h" + +#include "kis_previewwidgetbase.h" + +class TQWidget; +class KisProfile; +class KisFilter; +class KisFilterConfiguration; +class TQTimer; +class KisLabelProgress; + +/** + * A widget that can be used by plugins to show a preview of the effect of the + * plugin to the user. This is a convenience class thand handily packs a source and a + * preview view together with a zoom button. + * It would be nice if every plugin that needs to show a preview + * (maybe not those that create a new image) would use this. This can prevent the distracting + * effect the GIMP has with a different preview for almost every filter. + */ +class KisPreviewWidget : public PreviewWidgetBase +{ + Q_OBJECT + TQ_OBJECT + +public: + /** Constructs the widget */ + KisPreviewWidget( TQWidget* tqparent = 0, const char* name = 0 ); + virtual ~KisPreviewWidget(); + + /** returns if the preview is automatically updated */ + bool getAutoUpdate() const; + + void wheelEvent(TQWheelEvent * e); + + /** Instructs the KisPreviewWidget to eventually update the preview. + * KisPreviewWidget delays the actual running of the filter for 500ms + * so if the user is changing a configuration setting, it won't run multiple time. + * @param filter to run on the image + * @config to use when filtering. + */ + void runFilter(KisFilter * filter, KisFilterConfiguration * config); + +public slots: + + /** Sets the preview to use the layer specified as argument */ + void slotSetDevice(KisPaintDeviceSP dev); + + /** Enables or disables the automatically updating of the preview */ + void slotSetAutoUpdate(bool set); + + /** Toggle between display preview and display original */ + void setPreviewDisplayed(bool v); + + /** use to indicate that the preview need to be updated. */ + void needUpdate(); + +signals: + /** This is emitted when the position or zoom factor of the widget has changed */ + void updated(); + +private slots: + + void zoomIn(); + void zoomOut(); + void zoomOneToOne(); + + /** + * Called when the "Force Update" button is clicked + */ + void forceUpdate(); + + /** + * Updates the zoom and redisplays either the original or the preview (filtered) image + */ + void updateZoom(); + + /** Internal method which actually runs the filter + */ + void runFilterHelper(); + +private: + /** + * Recalculates the zoom factor + */ + void zoomChanged(const double zoom); + + bool m_autoupdate; /// Flag indicating that the widget should auto update whenever a setting is changed + bool m_previewIsDisplayed; /// Flag indicating whether the filtered or original image is displayed + + TQImage m_scaledOriginal; /// TQImage copy of the original image + bool m_dirtyOriginal; /// flag indicating that the original image is dirty + KisPaintDeviceSP m_origDevice; /// Pointer to the original image + + TQImage m_scaledPreview; /// TQImage copy of the filtered image + bool m_dirtyPreview; /// flag indicating that the preview image is dirty + KisPaintDeviceSP m_previewDevice; /// Pointer to the preview image + KisImageSP m_scaledImage; /// Scaled image copied from the original + + double m_filterZoom; /// Zoom amount when the filtering occurred + double m_zoom; /// Current zoom amount + KisProfile * m_profile; /// the color profile to use when converting to TQImage + + KisLabelProgress *m_progress; /// Progress bar of the preview. + + TQTimer * m_zoomTimer; /// Timer used to update the view whenever the zoom changes + TQTimer * m_filterTimer; /// Timer used to update the view whenever the filter changes + KisFilter * m_filter; /// Filter used + KisFilterConfiguration * m_config; /// Configuration used + bool m_firstFilter; /// Flag to determine if we should delay the first filter or not + bool m_firstZoom; /// Flag to determine if we should delay the first zoom or not +}; + +#endif diff --git a/chalk/ui/kis_previewwidgetbase.ui b/chalk/ui/kis_previewwidgetbase.ui new file mode 100644 index 00000000..6ee64019 --- /dev/null +++ b/chalk/ui/kis_previewwidgetbase.ui @@ -0,0 +1,271 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>PreviewWidgetBase</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>PreviewWidgetBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>588</width> + <height>500</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="tqminimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="TQGroupBox"> + <property name="name"> + <cstring>m_groupBox</cstring> + </property> + <property name="title"> + <string>Preview</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="ImageViewer"> + <property name="name"> + <cstring>m_preview</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="tqminimumSize"> + <size> + <width>200</width> + <height>150</height> + </size> + </property> + <property name="tqmaximumSize"> + <size> + <width>1000</width> + <height>1000</height> + </size> + </property> + </widget> + </vbox> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQButtonGroup"> + <property name="name"> + <cstring>buttonGroup1</cstring> + </property> + <property name="frameShape"> + <enum>GroupBoxPanel</enum> + </property> + <property name="title"> + <string></string> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQRadioButton"> + <property name="name"> + <cstring>radioBtnPreview</cstring> + </property> + <property name="text"> + <string>Pr&eview</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Preview modified layer</string> + </property> + </widget> + <widget class="TQRadioButton"> + <property name="name"> + <cstring>radioBtnOriginal</cstring> + </property> + <property name="text"> + <string>Ori&ginal</string> + </property> + <property name="toolTip" stdset="0"> + <string>Show original layer</string> + </property> + </widget> + </hbox> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout5</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KPushButton"> + <property name="name"> + <cstring>btnZoomOut</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="toolTip" stdset="0"> + <string>Zoom Out</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>btnZoomIn</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="toolTip" stdset="0"> + <string>Zoom In</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>btnZoomOneToOne</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="toolTip" stdset="0"> + <string>1 : 1</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>btnUpdate</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="toolTip" stdset="0"> + <string>Update preview</string> + </property> + </widget> + </hbox> + </widget> + <widget class="TQCheckBox"> + <property name="name"> + <cstring>checkBoxAutoUpdate</cstring> + </property> + <property name="text"> + <string>&Autoupdate</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Automatically update the preview whenever the filter settings change</string> + </property> + </widget> + </vbox> + </widget> + <widget class="TQFrame"> + <property name="name"> + <cstring>frmProgress</cstring> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>Raised</enum> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<customwidgets> + <customwidget> + <class>ImageViewer</class> + <header location="local">imageviewer.h</header> + <sizehint> + <width>-1</width> + <height>-1</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image0</pixmap> + <signal>moved(QPoint)</signal> + <signal>moving(QPoint)</signal> + <signal>startMoving(QPoint)</signal> + <slot access="public" specifier="">zoomIn()</slot> + <slot access="public" specifier="">slot()</slot> + <slot access="public" specifier="">zoomOut()</slot> + <slot access="public" specifier="">slot()</slot> + <slot access="public" specifier="">slot()</slot> + <slot access="public" specifier="">slotMoving(QPoint)</slot> + <slot access="public" specifier="">slotMoved(QPoint)</slot> + <slot access="public" specifier="">slot()</slot> + <slot access="public" specifier="">slotStartMoving(QPoint)</slot> + </customwidget> +</customwidgets> +<images> + <image name="image0"> + <data format="XBM.GZ" length="79">789c534e494dcbcc4b554829cdcdad8c2fcf4c29c95030e0524611cd48cd4ccf28010a1797249664262b2467241641a592324b8aa363156c15aab914146aadb90067111b1f</data> + </image> +</images> +<tqlayoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>imageviewer.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> +</includehints> +</UI> diff --git a/chalk/ui/kis_qpaintdevice_canvas.cc b/chalk/ui/kis_qpaintdevice_canvas.cc new file mode 100644 index 00000000..1f7def2d --- /dev/null +++ b/chalk/ui/kis_qpaintdevice_canvas.cc @@ -0,0 +1,120 @@ +/* + * Copyright (c) 1999 Matthias Elter <me@kde.org> + * Copyright (c) 2004 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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.g + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_qpaintdevice_canvas.h" +#include "kis_qpaintdevice_canvas_painter.h" +#include <kdebug.h> + +KisTQPaintDeviceCanvasWidget::KisTQPaintDeviceCanvasWidget(TQWidget *tqparent, const char *name) + : TQWidget(tqparent, name) +{ +} + +KisTQPaintDeviceCanvasWidget::~KisTQPaintDeviceCanvasWidget() +{ +} + +void KisTQPaintDeviceCanvasWidget::paintEvent(TQPaintEvent *e) +{ + widgetGotPaintEvent(e); +} + +void KisTQPaintDeviceCanvasWidget::mousePressEvent(TQMouseEvent *e) +{ + widgetGotMousePressEvent(e); +} + +void KisTQPaintDeviceCanvasWidget::mouseReleaseEvent(TQMouseEvent *e) +{ + widgetGotMouseReleaseEvent(e); +} + +void KisTQPaintDeviceCanvasWidget::mouseDoubleClickEvent(TQMouseEvent *e) +{ + widgetGotMouseDoubleClickEvent(e); +} + +void KisTQPaintDeviceCanvasWidget::mouseMoveEvent(TQMouseEvent *e) +{ + widgetGotMouseMoveEvent(e); +} + +void KisTQPaintDeviceCanvasWidget::tabletEvent(TQTabletEvent *e) +{ + widgetGotTabletEvent(e); +} + +void KisTQPaintDeviceCanvasWidget::enterEvent(TQEvent *e) +{ + widgetGotEnterEvent(e); +} + +void KisTQPaintDeviceCanvasWidget::leaveEvent(TQEvent *e) +{ + widgetGotLeaveEvent(e); +} + +void KisTQPaintDeviceCanvasWidget::wheelEvent(TQWheelEvent *e) +{ + widgetGotWheelEvent(e); +} + +void KisTQPaintDeviceCanvasWidget::keyPressEvent(TQKeyEvent *e) +{ + widgetGotKeyPressEvent(e); +} + +void KisTQPaintDeviceCanvasWidget::keyReleaseEvent(TQKeyEvent *e) +{ + widgetGotKeyReleaseEvent(e); +} + +void KisTQPaintDeviceCanvasWidget::dragEnterEvent(TQDragEnterEvent *e) +{ + widgetGotDragEnterEvent(e); +} + +void KisTQPaintDeviceCanvasWidget::dropEvent(TQDropEvent *e) +{ + widgetGotDropEvent(e); +} + +#ifdef Q_WS_X11 + +bool KisTQPaintDeviceCanvasWidget::x11Event(XEvent *event) +{ + return KisCanvasWidget::x11Event(event, x11Display(), winId(), mapToGlobal(TQPoint(0, 0))); +} + +#endif // Q_WS_X11 + +KisCanvasWidgetPainter *KisTQPaintDeviceCanvasWidget::createPainter() +{ + return new KisTQPaintDeviceCanvasPainter(TQT_TQPAINTDEVICE(this)); +} + +#if defined(EXTENDED_X11_TABLET_SUPPORT) +void KisTQPaintDeviceCanvasWidget::selectTabletDeviceEvents() +{ + KisCanvasWidget::selectTabletDeviceEvents(this); +} +#endif + diff --git a/chalk/ui/kis_qpaintdevice_canvas.h b/chalk/ui/kis_qpaintdevice_canvas.h new file mode 100644 index 00000000..ae688248 --- /dev/null +++ b/chalk/ui/kis_qpaintdevice_canvas.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 1999 Matthias Elter <me@kde.org> + * Copyright (c) 2004 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_TQPAINTDEVICE_CANVAS_H_ +#define KIS_TQPAINTDEVICE_CANVAS_H_ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <tqwidget.h> + +#include "kis_global.h" +#include "kis_canvas.h" + +#ifdef Q_MOC_RUN +#define Q_WS_X11 +#endif // Q_MOC_RUN + +#ifdef Q_WS_X11 +#include <X11/Xlib.h> +#endif // Q_WS_X11 + +class KisTQPaintDeviceCanvasWidget : public virtual TQWidget, public virtual KisCanvasWidget { +public: + KisTQPaintDeviceCanvasWidget(TQWidget *tqparent = 0, const char *name = 0); + ~KisTQPaintDeviceCanvasWidget(); + + virtual KisCanvasWidgetPainter *createPainter(); + +#if defined(EXTENDED_X11_TABLET_SUPPORT) + virtual void selectTabletDeviceEvents(); +#endif + +protected: + virtual void paintEvent(TQPaintEvent *event); + virtual void mousePressEvent(TQMouseEvent *event); + virtual void mouseReleaseEvent(TQMouseEvent *event); + virtual void mouseDoubleClickEvent(TQMouseEvent *event); + virtual void mouseMoveEvent(TQMouseEvent *event); + virtual void tabletEvent(TQTabletEvent *event); + virtual void enterEvent(TQEvent *event ); + virtual void leaveEvent(TQEvent *event); + virtual void wheelEvent(TQWheelEvent *event); + virtual void keyPressEvent(TQKeyEvent *event); + virtual void keyReleaseEvent(TQKeyEvent *event); + virtual void dragEnterEvent(TQDragEnterEvent *event); + virtual void dropEvent(TQDropEvent *event); +#ifdef Q_WS_X11 + bool x11Event(XEvent *event); +#endif // Q_WS_X11 +}; + +#endif // KIS_TQPAINTDEVICE_CANVAS_H_ + diff --git a/chalk/ui/kis_qpaintdevice_canvas_painter.cc b/chalk/ui/kis_qpaintdevice_canvas_painter.cc new file mode 100644 index 00000000..4233bc11 --- /dev/null +++ b/chalk/ui/kis_qpaintdevice_canvas_painter.cc @@ -0,0 +1,667 @@ +/* + * Copyright (c) 2005 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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.g + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_qpaintdevice_canvas_painter.h" + +KisTQPaintDeviceCanvasPainter::KisTQPaintDeviceCanvasPainter() +{ +} + +KisTQPaintDeviceCanvasPainter::KisTQPaintDeviceCanvasPainter(const TQPaintDevice *paintDevice) + : m_painter(const_cast<TQPaintDevice*>(paintDevice)) +{ +} + +KisTQPaintDeviceCanvasPainter::~KisTQPaintDeviceCanvasPainter() +{ +} + +bool KisTQPaintDeviceCanvasPainter::begin(KisCanvasWidget *canvasWidget, bool unclipped) +{ + TQWidget *widget = dynamic_cast<TQWidget *>(canvasWidget); + + if (widget != 0) { + return m_painter.tqbegin(TQT_TQPAINTDEVICE(widget), unclipped); + } else { + return false; + } +} + +bool KisTQPaintDeviceCanvasPainter::begin(const TQPaintDevice* paintDevice, bool unclipped) +{ + return m_painter.tqbegin(const_cast<TQPaintDevice*>(paintDevice), unclipped); +} + +bool KisTQPaintDeviceCanvasPainter::end() +{ + return m_painter.end(); +} + +void KisTQPaintDeviceCanvasPainter::save() +{ + m_painter.save(); +} + +void KisTQPaintDeviceCanvasPainter::restore() +{ + m_painter.restore(); +} + +TQFontMetrics KisTQPaintDeviceCanvasPainter::fontMetrics() const +{ + return m_painter.fontMetrics(); +} + +TQFontInfo KisTQPaintDeviceCanvasPainter::fontInfo() const +{ + return m_painter.fontInfo(); +} + +const TQFont& KisTQPaintDeviceCanvasPainter::font() const +{ + return m_painter.font(); +} + +void KisTQPaintDeviceCanvasPainter::setFont(const TQFont& font) +{ + m_painter.setFont(font); +} + +const TQPen& KisTQPaintDeviceCanvasPainter::pen() const +{ + return m_painter.pen(); +} + +void KisTQPaintDeviceCanvasPainter::setPen(const TQPen& pen) +{ + m_painter.setPen(pen); +} + +void KisTQPaintDeviceCanvasPainter::setPen(Qt::PenStyle penStyle) +{ + m_painter.setPen(penStyle); +} + +void KisTQPaintDeviceCanvasPainter::setPen(const TQColor& color) +{ + m_painter.setPen(color);; +} + +const TQBrush& KisTQPaintDeviceCanvasPainter::brush() const +{ + return m_painter.brush(); +} + +void KisTQPaintDeviceCanvasPainter::setBrush(const TQBrush& brush) +{ + m_painter.setBrush(brush); +} + +void KisTQPaintDeviceCanvasPainter::setBrush(TQt::BrushStyle brushStyle) +{ + m_painter.setBrush(brushStyle); +} + +void KisTQPaintDeviceCanvasPainter::setBrush(const TQColor& color) +{ + m_painter.setBrush(color); +} + +TQPoint KisTQPaintDeviceCanvasPainter::pos() const +{ + return m_painter.pos(); +} + +const TQColor& KisTQPaintDeviceCanvasPainter::backgroundColor() const +{ + return m_painter.backgroundColor(); +} + +void KisTQPaintDeviceCanvasPainter::setBackgroundColor(const TQColor& color) +{ + m_painter.setBackgroundColor(color); +} + +Qt::BGMode KisTQPaintDeviceCanvasPainter::backgroundMode() const +{ + return m_painter.backgroundMode(); +} + +void KisTQPaintDeviceCanvasPainter::setBackgroundMode(Qt::BGMode bgMode) +{ + m_painter.setBackgroundMode(bgMode); +} + +TQt::RasterOp KisTQPaintDeviceCanvasPainter::rasterOp() const +{ + return m_painter.rasterOp(); +} + +void KisTQPaintDeviceCanvasPainter::setRasterOp(TQt::RasterOp rasterOp) +{ + m_painter.setRasterOp(rasterOp); +} + +const TQPoint& KisTQPaintDeviceCanvasPainter::brushOrigin() const +{ + return m_painter.brushOrigin(); +} + +void KisTQPaintDeviceCanvasPainter::setBrushOrigin(int x, int y) +{ + m_painter.setBrushOrigin(x, y); +} + +void KisTQPaintDeviceCanvasPainter::setBrushOrigin(const TQPoint& origin) +{ + m_painter.setBrushOrigin(origin); +} + +bool KisTQPaintDeviceCanvasPainter::hasViewXForm() const +{ + return m_painter.hasViewXForm(); +} + +bool KisTQPaintDeviceCanvasPainter::hasWorldXForm() const +{ + return m_painter.hasWorldXForm(); +} + +void KisTQPaintDeviceCanvasPainter::setViewXForm(bool enable) +{ + m_painter.setViewXForm(enable); +} + +TQRect KisTQPaintDeviceCanvasPainter::window() const +{ + return m_painter.window(); +} + +void KisTQPaintDeviceCanvasPainter::setWindow(const TQRect& r) +{ + m_painter.setWindow(r); +} + +void KisTQPaintDeviceCanvasPainter::setWindow(int x, int y, int w, int h) +{ + m_painter.setWindow(x, y, w, h); +} + +TQRect KisTQPaintDeviceCanvasPainter::viewport() const +{ + return m_painter.viewport(); +} + +void KisTQPaintDeviceCanvasPainter::setViewport(const TQRect& r) +{ + m_painter.setViewport(r); +} + +void KisTQPaintDeviceCanvasPainter::setViewport(int x, int y, int w, int h) +{ + m_painter.setViewport(x, y, w, h); +} + +void KisTQPaintDeviceCanvasPainter::setWorldXForm(bool enable) +{ + m_painter.setWorldXForm(enable); +} + +const TQWMatrix& KisTQPaintDeviceCanvasPainter::tqworldMatrix() const +{ + return m_painter.tqworldMatrix(); +} + +void KisTQPaintDeviceCanvasPainter::setWorldMatrix(const TQWMatrix& matrix, bool combine) +{ + m_painter.setWorldMatrix(matrix, combine); +} + +void KisTQPaintDeviceCanvasPainter::saveWorldMatrix() +{ + m_painter.saveWorldMatrix(); +} + +void KisTQPaintDeviceCanvasPainter::restoreWorldMatrix() +{ + m_painter.restoreWorldMatrix(); +} + +void KisTQPaintDeviceCanvasPainter::scale(double sx, double sy) +{ + m_painter.scale(sx, sy); +} + +void KisTQPaintDeviceCanvasPainter::shear(double sh, double sv) +{ + m_painter.shear(sh, sv); +} + +void KisTQPaintDeviceCanvasPainter::rotate(double a) +{ + m_painter.rotate(a); +} + +void KisTQPaintDeviceCanvasPainter::translate(double dx, double dy) +{ + m_painter.translate(dx, dy); +} + +void KisTQPaintDeviceCanvasPainter::resetXForm() +{ + m_painter.resetXForm(); +} + +double KisTQPaintDeviceCanvasPainter::translationX() const +{ + return m_painter.translationX(); +} + +double KisTQPaintDeviceCanvasPainter::translationY() const +{ + return m_painter.translationY(); +} + +TQPoint KisTQPaintDeviceCanvasPainter::xForm(const TQPoint& point) const +{ + return m_painter.xForm(point); +} + +TQRect KisTQPaintDeviceCanvasPainter::xForm(const TQRect& r) const +{ + return m_painter.xForm(r); +} + +TQPointArray KisTQPaintDeviceCanvasPainter::xForm(const TQPointArray& pointArray) const +{ + return m_painter.xForm(pointArray); +} + +TQPointArray KisTQPaintDeviceCanvasPainter::xForm(const TQPointArray& pointArray, int index, int npoints) const +{ + return m_painter.xForm(pointArray, index, npoints); +} + +TQPoint KisTQPaintDeviceCanvasPainter::xFormDev(const TQPoint& point) const +{ + return m_painter.xFormDev(point); +} + +TQRect KisTQPaintDeviceCanvasPainter::xFormDev(const TQRect& r) const +{ + return m_painter.xFormDev(r); +} + +TQPointArray KisTQPaintDeviceCanvasPainter::xFormDev(const TQPointArray& pointArray) const +{ + return m_painter.xFormDev(pointArray); +} + +TQPointArray KisTQPaintDeviceCanvasPainter::xFormDev(const TQPointArray& pointArray, int index, int npoints) const +{ + return m_painter.xFormDev(pointArray, index, npoints); +} + +void KisTQPaintDeviceCanvasPainter::setClipping(bool enable) +{ + m_painter.setClipping(enable); +} + +bool KisTQPaintDeviceCanvasPainter::hasClipping() const +{ + return m_painter.hasClipping(); +} + +TQRegion KisTQPaintDeviceCanvasPainter::clipRegion(TQPainter::CoordinateMode mode) const +{ + return m_painter.clipRegion(mode); +} + +void KisTQPaintDeviceCanvasPainter::setClipRect(const TQRect& r, TQPainter::CoordinateMode mode) +{ + m_painter.setClipRect(r, mode); +} + +void KisTQPaintDeviceCanvasPainter::setClipRect(int x, int y, int w, int h, TQPainter::CoordinateMode mode) +{ + m_painter.setClipRect(x, y, w, h, mode); +} + +void KisTQPaintDeviceCanvasPainter::setClipRegion(const TQRegion& rgn, TQPainter::CoordinateMode mode) +{ + m_painter.setClipRegion(rgn, mode); +} + +void KisTQPaintDeviceCanvasPainter::drawPoint(int x, int y) +{ + m_painter.drawPoint(x, y); +} + +void KisTQPaintDeviceCanvasPainter::drawPoint(const TQPoint& point) +{ + m_painter.drawPoint(point); +} + +void KisTQPaintDeviceCanvasPainter::drawPoints(const TQPointArray& pointArray, int index, int npoints) +{ + m_painter.drawPoints(pointArray, index, npoints); +} + +void KisTQPaintDeviceCanvasPainter::moveTo(int x, int y) +{ + m_painter.moveTo(x, y); +} + +void KisTQPaintDeviceCanvasPainter::moveTo(const TQPoint& point) +{ + m_painter.moveTo(point); +} + +void KisTQPaintDeviceCanvasPainter::lineTo(int x, int y) +{ + m_painter.lineTo(x, y); +} + +void KisTQPaintDeviceCanvasPainter::lineTo(const TQPoint& point) +{ + m_painter.lineTo(point); +} + +void KisTQPaintDeviceCanvasPainter::drawLine(int x1, int y1, int x2, int y2) +{ + m_painter.drawLine(x1, y1, x2, y2); +} + +void KisTQPaintDeviceCanvasPainter::drawLine(const TQPoint& start, const TQPoint& end) +{ + m_painter.drawLine(start, end); +} + +void KisTQPaintDeviceCanvasPainter::drawRect(int x, int y, int w, int h) +{ + m_painter.drawRect(x, y, w, h); +} + +void KisTQPaintDeviceCanvasPainter::drawRect(const TQRect& r) +{ + m_painter.drawRect(r); +} + +void KisTQPaintDeviceCanvasPainter::drawWinFocusRect(int x, int y, int w, int h) +{ + m_painter.drawWinFocusRect(x, y, w, h); +} + +void KisTQPaintDeviceCanvasPainter::drawWinFocusRect(int x, int y, int w, int h, const TQColor& bgColor) +{ + m_painter.drawWinFocusRect(x, y, w, h, bgColor); +} + +void KisTQPaintDeviceCanvasPainter::drawWinFocusRect(const TQRect& r) +{ + m_painter.drawWinFocusRect(r); +} + +void KisTQPaintDeviceCanvasPainter::drawWinFocusRect(const TQRect& r, const TQColor& bgColor) +{ + m_painter.drawWinFocusRect(r, bgColor); +} + +void KisTQPaintDeviceCanvasPainter::drawRoundRect(int x, int y, int w, int h, int xRnd, int yRnd) +{ + m_painter.drawRoundRect(x, y, w, h, xRnd, yRnd); +} + +void KisTQPaintDeviceCanvasPainter::drawRoundRect(const TQRect& r, int xRnd, int yRnd) +{ + m_painter.drawRoundRect(r, xRnd, yRnd); +} + +void KisTQPaintDeviceCanvasPainter::drawEllipse(int x, int y, int w, int h) +{ + m_painter.drawEllipse(x, y, w, h); +} + +void KisTQPaintDeviceCanvasPainter::drawEllipse(const TQRect& r) +{ + m_painter.drawEllipse(r); +} + +void KisTQPaintDeviceCanvasPainter::drawArc(int x, int y, int w, int h, int a, int alen) +{ + m_painter.drawArc(x, y, w, h, a, alen); +} + +void KisTQPaintDeviceCanvasPainter::drawArc(const TQRect& r, int a, int alen) +{ + m_painter.drawArc(r, a, alen); +} + +void KisTQPaintDeviceCanvasPainter::drawPie(int x, int y, int w, int h, int a, int alen) +{ + m_painter.drawPie(x, y, w, h, a, alen); +} + +void KisTQPaintDeviceCanvasPainter::drawPie(const TQRect& r, int a, int alen) +{ + m_painter.drawPie(r, a, alen); +} + +void KisTQPaintDeviceCanvasPainter::drawChord(int x, int y, int w, int h, int a, int alen) +{ + m_painter.drawChord(x, y, w, h, a, alen); +} + +void KisTQPaintDeviceCanvasPainter::drawChord(const TQRect& r, int a, int alen) +{ + m_painter.drawChord(r, a, alen); +} + +void KisTQPaintDeviceCanvasPainter::drawLineSegments(const TQPointArray& pointArray, int index, int nlines) +{ + m_painter.drawLineSegments(pointArray, index, nlines); +} + +void KisTQPaintDeviceCanvasPainter::drawPolyline(const TQPointArray& pointArray, int index, int npoints) +{ + m_painter.tqdrawPolyline(pointArray, index, npoints); +} + +void KisTQPaintDeviceCanvasPainter::drawPolygon(const TQPointArray& pointArray, bool winding, int index, int npoints) +{ + m_painter.tqdrawPolygon(pointArray, winding, index, npoints); +} + +void KisTQPaintDeviceCanvasPainter::drawConvexPolygon(const TQPointArray& pointArray, int index, int npoints) +{ + m_painter.tqdrawConvexPolygon(pointArray, index, npoints); +} + +void KisTQPaintDeviceCanvasPainter::drawCubicBezier(const TQPointArray& pointArray, int index) +{ + m_painter.drawCubicBezier(pointArray, index); +} + +void KisTQPaintDeviceCanvasPainter::drawPixmap(int x, int y, const TQPixmap& pixmap, int sx, int sy, int sw, int sh) +{ + m_painter.drawPixmap(x, y, pixmap, sx, sy, sw, sh); +} + +void KisTQPaintDeviceCanvasPainter::drawPixmap(const TQPoint& point, const TQPixmap& pixmap, const TQRect& sr) +{ + m_painter.drawPixmap(point, pixmap, sr); +} + +void KisTQPaintDeviceCanvasPainter::drawPixmap(const TQPoint& point, const TQPixmap& pixmap) +{ + m_painter.drawPixmap(point, pixmap); +} + +void KisTQPaintDeviceCanvasPainter::drawPixmap(const TQRect& r, const TQPixmap& pixmap) +{ + m_painter.drawPixmap(r, pixmap); +} + +void KisTQPaintDeviceCanvasPainter::drawImage(int x, int y, const TQImage& image, int sx, int sy, int sw, int sh, int conversionFlags) +{ + m_painter.drawImage(x, y, image, sx, sy, sw, sh, conversionFlags); +} + +void KisTQPaintDeviceCanvasPainter::drawImage(const TQPoint& point, const TQImage& image, const TQRect& sr, int conversionFlags) +{ + m_painter.drawImage(point, image, sr, conversionFlags); +} + +void KisTQPaintDeviceCanvasPainter::drawImage(const TQPoint& point, const TQImage& image, int conversion_flags) +{ + m_painter.drawImage(point, image, conversion_flags); +} + +void KisTQPaintDeviceCanvasPainter::drawImage(const TQRect& r, const TQImage& image) +{ + m_painter.drawImage(r, image); +} + +void KisTQPaintDeviceCanvasPainter::drawTiledPixmap(int x, int y, int w, int h, const TQPixmap& pixmap, int sx, int sy) +{ + m_painter.drawTiledPixmap(x, y, w, h, pixmap, sx, sy); +} + +void KisTQPaintDeviceCanvasPainter::drawTiledPixmap(const TQRect& r, const TQPixmap& pixmap, const TQPoint& point) +{ + m_painter.drawTiledPixmap(r, pixmap, point); +} + +void KisTQPaintDeviceCanvasPainter::drawTiledPixmap(const TQRect& r, const TQPixmap& pixmap) +{ + m_painter.drawTiledPixmap(r, pixmap); +} + +void KisTQPaintDeviceCanvasPainter::fillRect(int x, int y, int w, int h, const TQBrush& brush) +{ + m_painter.fillRect(x, y, w, h, brush); +} + +void KisTQPaintDeviceCanvasPainter::fillRect(const TQRect& r, const TQBrush& brush) +{ + m_painter.fillRect(r, brush); +} + +void KisTQPaintDeviceCanvasPainter::eraseRect(int x, int y, int w, int h) +{ + m_painter.eraseRect(x, y, w, h); +} + +void KisTQPaintDeviceCanvasPainter::eraseRect(const TQRect& r) +{ + m_painter.eraseRect(r); +} + +void KisTQPaintDeviceCanvasPainter::drawText(int x, int y, const TQString& text, int len, TQPainter::TextDirection dir) +{ + m_painter.drawText(x, y, text, len, dir); +} + +void KisTQPaintDeviceCanvasPainter::drawText(const TQPoint& point, const TQString& text, int len, TQPainter::TextDirection dir) +{ + m_painter.drawText(point, text, len, dir); +} + +void KisTQPaintDeviceCanvasPainter::drawText(int x, int y, const TQString& text, int pos, int len, TQPainter::TextDirection dir) +{ + m_painter.drawText(x, y, text, pos, len, dir); +} + +void KisTQPaintDeviceCanvasPainter::drawText(const TQPoint& point, const TQString& text, int pos, int len, TQPainter::TextDirection dir) +{ + m_painter.drawText(point, text, pos, len, dir); +} + +void KisTQPaintDeviceCanvasPainter::drawText(int x, int y, int w, int h, int flags, const TQString& text, int len, TQRect *br, TQTextParag **intern) +{ +#ifdef USE_QT4 + printf("[WARNING] KisTQPaintDeviceCanvasPainter::drawText partially implemented\n\r"); + m_painter.drawText(x, y, w, h, flags, text, len, br); +#else // USE_QT4 + m_painter.drawText(x, y, w, h, flags, text, len, br, intern); +#endif // USE_QT4 +} + +void KisTQPaintDeviceCanvasPainter::drawText(const TQRect& r, int flags, const TQString& text, int len, TQRect *br, TQTextParag **intern) +{ +#ifdef USE_QT4 + printf("[WARNING] KisTQPaintDeviceCanvasPainter::drawText partially implemented\n\r"); + m_painter.drawText(r, flags, text, len, br); +#else // USE_QT4 + m_painter.drawText(r, flags, text, len, br, intern); +#endif // USE_QT4 +} + +void KisTQPaintDeviceCanvasPainter::tqdrawTextItem(int x, int y, const TQTextItem& ti, int textflags) +{ + m_painter.tqdrawTextItem(x, y, ti, textflags); +} + +void KisTQPaintDeviceCanvasPainter::tqdrawTextItem(const TQPoint& p, const TQTextItem& ti, int textflags) +{ + m_painter.tqdrawTextItem(p, ti, textflags); +} + +TQRect KisTQPaintDeviceCanvasPainter::boundingRect(int x, int y, int w, int h, int flags, const TQString& text, int len, TQTextParag **intern) +{ +#ifdef USE_QT4 + printf("[WARNING] KisTQPaintDeviceCanvasPainter::boundingRect partially implemented\n\r"); + return m_painter.boundingRect(x, y, w, h, flags, text, len); +#else // USE_QT4 + return m_painter.boundingRect(x, y, w, h, flags, text, len, intern); +#endif // USE_QT4 +} + +TQRect KisTQPaintDeviceCanvasPainter::boundingRect(const TQRect& r, int flags, const TQString& text, int len, TQTextParag **intern) +{ +#ifdef USE_QT4 + printf("[WARNING] KisTQPaintDeviceCanvasPainter::boundingRect partially implemented\n\r"); + return m_painter.boundingRect(r, flags, text, len); +#else // USE_QT4 + return m_painter.boundingRect(r, flags, text, len, intern); +#endif // USE_QT4 +} + +int KisTQPaintDeviceCanvasPainter::tabStops() const +{ + return m_painter.tabStops(); +} + +void KisTQPaintDeviceCanvasPainter::setTabStops(int ts) +{ + m_painter.setTabStops(ts); +} + +int *KisTQPaintDeviceCanvasPainter::tabArray() const +{ + return m_painter.tabArray(); +} + +void KisTQPaintDeviceCanvasPainter::setTabArray(int *ts) +{ + m_painter.setTabArray(ts); +} + + diff --git a/chalk/ui/kis_qpaintdevice_canvas_painter.h b/chalk/ui/kis_qpaintdevice_canvas_painter.h new file mode 100644 index 00000000..0dca7322 --- /dev/null +++ b/chalk/ui/kis_qpaintdevice_canvas_painter.h @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2005 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_TQPAINTDEVICE_CANVAS_PAINTER_H_ +#define KIS_TQPAINTDEVICE_CANVAS_PAINTER_H_ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <tqwidget.h> +#include <tqpainter.h> + +#include "kis_global.h" +#include "kis_canvas_painter.h" + +class KisTQPaintDeviceCanvasPainter : public KisCanvasWidgetPainter { +public: + KisTQPaintDeviceCanvasPainter(); + KisTQPaintDeviceCanvasPainter(const TQPaintDevice *paintDevice); + virtual ~KisTQPaintDeviceCanvasPainter(); + + bool begin(const TQPaintDevice* paintDevice, bool unclipped = false); + + virtual bool begin(KisCanvasWidget *canvasWidget, bool unclipped = false); + virtual bool end(); + + virtual void save(); + virtual void restore(); + + virtual TQFontMetrics fontMetrics() const; + virtual TQFontInfo fontInfo() const; + + virtual const TQFont& font() const; + virtual void setFont(const TQFont&); + virtual const TQPen& pen() const; + virtual void setPen(const TQPen&); + virtual void setPen(Qt::PenStyle); + virtual void setPen(const TQColor&); + virtual const TQBrush&brush() const; + virtual void setBrush(const TQBrush&); + virtual void setBrush(TQt::BrushStyle); + virtual void setBrush(const TQColor&); + virtual TQPoint pos() const; + + virtual const TQColor&backgroundColor() const; + virtual void setBackgroundColor(const TQColor&); + virtual Qt::BGMode backgroundMode() const; + virtual void setBackgroundMode(Qt::BGMode); + virtual TQt::RasterOp rasterOp() const; + virtual void setRasterOp(TQt::RasterOp); + virtual const TQPoint&brushOrigin() const; + virtual void setBrushOrigin(int x, int y); + virtual void setBrushOrigin(const TQPoint&); + + virtual bool hasViewXForm() const; + virtual bool hasWorldXForm() const; + + virtual void setViewXForm(bool); + virtual TQRect window() const; + virtual void setWindow(const TQRect&); + virtual void setWindow(int x, int y, int w, int h); + virtual TQRect viewport() const; + virtual void setViewport(const TQRect&); + virtual void setViewport(int x, int y, int w, int h); + + virtual void setWorldXForm(bool); + virtual const TQWMatrix&tqworldMatrix() const; + virtual void setWorldMatrix(const TQWMatrix&, bool combine=FALSE); + + virtual void saveWorldMatrix(); + virtual void restoreWorldMatrix(); + + virtual void scale(double sx, double sy); + virtual void shear(double sh, double sv); + virtual void rotate(double a); + + virtual void translate(double dx, double dy); + virtual void resetXForm(); + virtual double translationX() const; + virtual double translationY() const; + + virtual TQPoint xForm(const TQPoint&) const; + virtual TQRect xForm(const TQRect&) const; + virtual TQPointArray xForm(const TQPointArray&) const; + virtual TQPointArray xForm(const TQPointArray&, int index, int npoints) const; + virtual TQPoint xFormDev(const TQPoint&) const; + virtual TQRect xFormDev(const TQRect&) const; + virtual TQPointArray xFormDev(const TQPointArray&) const; + virtual TQPointArray xFormDev(const TQPointArray&, int index, int npoints) const; + + virtual void setClipping(bool); + virtual bool hasClipping() const; + virtual TQRegion clipRegion(TQPainter::CoordinateMode = TQPainter::CoordDevice) const; + virtual void setClipRect(const TQRect&, TQPainter::CoordinateMode = TQPainter::CoordDevice); + virtual void setClipRect(int x, int y, int w, int h, TQPainter::CoordinateMode = TQPainter::CoordDevice); + virtual void setClipRegion(const TQRegion&, TQPainter::CoordinateMode = TQPainter::CoordDevice); + + virtual void drawPoint(int x, int y); + virtual void drawPoint(const TQPoint&); + virtual void drawPoints(const TQPointArray& a, int index=0, int npoints=-1); + virtual void moveTo(int x, int y); + virtual void moveTo(const TQPoint&); + virtual void lineTo(int x, int y); + virtual void lineTo(const TQPoint&); + virtual void drawLine(int x1, int y1, int x2, int y2); + virtual void drawLine(const TQPoint&, const TQPoint&); + virtual void drawRect(int x, int y, int w, int h); + virtual void drawRect(const TQRect&); + virtual void drawWinFocusRect(int x, int y, int w, int h); + virtual void drawWinFocusRect(int x, int y, int w, int h, const TQColor&bgColor); + virtual void drawWinFocusRect(const TQRect&); + virtual void drawWinFocusRect(const TQRect&, const TQColor&bgColor); + virtual void drawRoundRect(int x, int y, int w, int h, int = 25, int = 25); + virtual void drawRoundRect(const TQRect&, int = 25, int = 25); + virtual void drawEllipse(int x, int y, int w, int h); + virtual void drawEllipse(const TQRect&); + virtual void drawArc(int x, int y, int w, int h, int a, int alen); + virtual void drawArc(const TQRect&, int a, int alen); + virtual void drawPie(int x, int y, int w, int h, int a, int alen); + virtual void drawPie(const TQRect&, int a, int alen); + virtual void drawChord(int x, int y, int w, int h, int a, int alen); + virtual void drawChord(const TQRect&, int a, int alen); + virtual void drawLineSegments(const TQPointArray&, int index=0, int nlines=-1); + virtual void drawPolyline(const TQPointArray&, int index=0, int npoints=-1); + virtual void drawPolygon(const TQPointArray&, bool winding=FALSE, int index=0, int npoints=-1); + virtual void drawConvexPolygon(const TQPointArray&, int index=0, int npoints=-1); + virtual void drawCubicBezier(const TQPointArray&, int index=0); + virtual void drawPixmap(int x, int y, const TQPixmap&, int sx=0, int sy=0, int sw=-1, int sh=-1); + virtual void drawPixmap(const TQPoint&, const TQPixmap&, const TQRect&sr); + virtual void drawPixmap(const TQPoint&, const TQPixmap&); + virtual void drawPixmap(const TQRect&, const TQPixmap&); + virtual void drawImage(int x, int y, const TQImage&, int sx = 0, int sy = 0, int sw = -1, int sh = -1, int conversionFlags = 0); + virtual void drawImage(const TQPoint&, const TQImage&, const TQRect&sr, int conversionFlags = 0); + virtual void drawImage(const TQPoint&, const TQImage&, int conversion_flags = 0); + virtual void drawImage(const TQRect&, const TQImage&); + virtual void drawTiledPixmap(int x, int y, int w, int h, const TQPixmap&, int sx=0, int sy=0); + virtual void drawTiledPixmap(const TQRect&, const TQPixmap&, const TQPoint&); + virtual void drawTiledPixmap(const TQRect&, const TQPixmap&); + //virtual void drawPicture(const TQPicture&); + //virtual void drawPicture(int x, int y, const TQPicture&); + //virtual void drawPicture(const TQPoint&, const TQPicture&); + + virtual void fillRect(int x, int y, int w, int h, const TQBrush&); + virtual void fillRect(const TQRect&, const TQBrush&); + virtual void eraseRect(int x, int y, int w, int h); + virtual void eraseRect(const TQRect&); + + virtual void drawText(int x, int y, const TQString&, int len = -1, TQPainter::TextDirection dir = TQPainter::Auto); + virtual void drawText(const TQPoint&, const TQString&, int len = -1, TQPainter::TextDirection dir = TQPainter::Auto); + + virtual void drawText(int x, int y, const TQString&, int pos, int len, TQPainter::TextDirection dir = TQPainter::Auto); + virtual void drawText(const TQPoint&p, const TQString&, int pos, int len, TQPainter::TextDirection dir = TQPainter::Auto); + + virtual void drawText(int x, int y, int w, int h, int flags, const TQString&, int len = -1, TQRect *br=0, TQTextParag **intern=0); + virtual void drawText(const TQRect&, int flags, const TQString&, int len = -1, TQRect *br=0, TQTextParag **intern=0); + + virtual void tqdrawTextItem(int x, int y, const TQTextItem&ti, int textflags = 0); + virtual void tqdrawTextItem(const TQPoint& p, const TQTextItem&ti, int textflags = 0); + + virtual TQRect boundingRect(int x, int y, int w, int h, int flags, const TQString&, int len = -1, TQTextParag **intern=0); + virtual TQRect boundingRect(const TQRect&, int flags, const TQString&, int len = -1, TQTextParag **intern=0); + + virtual int tabStops() const; + virtual void setTabStops(int); + virtual int *tabArray() const; + virtual void setTabArray(int *); + +protected: + TQPainter m_painter; +}; + +#endif // KIS_TQPAINTDEVICE_CANVAS_PAINTER_H_ + diff --git a/chalk/ui/kis_resource_mediator.cc b/chalk/ui/kis_resource_mediator.cc new file mode 100644 index 00000000..204a1033 --- /dev/null +++ b/chalk/ui/kis_resource_mediator.cc @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2003 Patrick Julien <freak@codepimps.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include <koIconChooser.h> + +#include "kdebug.h" + +#include "kis_icon_item.h" +#include "kis_resource.h" +#include "kis_itemchooser.h" +#include "kis_resourceserver.h" +#include "kis_resource_mediator.h" + +KisResourceMediator::KisResourceMediator(KisItemChooser *chooser, + TQObject *tqparent, + const char *name) : super(tqparent, name), m_chooser(chooser) +{ + Q_ASSERT(chooser); + m_activeItem = 0; + + connect(m_chooser, TQT_SIGNAL(selected(KoIconItem*)), TQT_SLOT(setActiveItem(KoIconItem*))); +} + +KisResourceMediator::~KisResourceMediator() +{ +} + +void KisResourceMediator::connectServer(KisResourceServerBase* rServer) +{ + // Add the initially loaded items + TQValueList<KisResource*> resources = rServer->resources(); + TQValueList<KisResource*>::iterator it; + for ( it = resources.begin(); it != resources.end(); ++it ) + rServerAddedResource( *it ); + + // And connect to the server permanently, so that we may recieve updates afterwards + connect(rServer, TQT_SIGNAL(resourceAdded(KisResource*)), + this, TQT_SLOT(rServerAddedResource(KisResource*))); +} + +KisResource *KisResourceMediator::currentResource() const +{ + if (m_activeItem) { + Q_ASSERT(dynamic_cast<KisIconItem*>(m_activeItem)); + return static_cast<KisIconItem*>(m_activeItem)->resource(); + } + + return 0; +} + +KisIconItem *KisResourceMediator::itemFor(KisResource *r) const +{ + if(m_items.tqcontains(r)) + { + return m_items[r]; + } + return 0; +} + +KisResource *KisResourceMediator::resourceFor(KoIconItem *item) const +{ + KisIconItem *kisitem = dynamic_cast<KisIconItem*>(item); + + return kisitem ? kisitem->resource() : 0; +} + +KisResource *KisResourceMediator::resourceFor(KisIconItem *item) const +{ + return item ? item->resource() : 0; +} + +TQWidget *KisResourceMediator::chooserWidget() const +{ + return m_chooser; +} + +void KisResourceMediator::setActiveItem(KoIconItem *item) +{ + KisIconItem *kisitem = dynamic_cast<KisIconItem*>(item); + + if (kisitem) { + m_activeItem = kisitem; + m_chooser->setCurrent(item); + emit activatedResource(kisitem ? kisitem->resource() : 0); + } +} + +void KisResourceMediator::rServerAddedResource(KisResource *resource) +{ + if (resource && resource->valid()) { + + KisIconItem *item = new KisIconItem(resource); + Q_CHECK_PTR(item); + + m_items[resource] = item; + + m_chooser->addItem(item); + if (m_activeItem == 0) setActiveItem(item); + } +} + +#include "kis_resource_mediator.moc" + diff --git a/chalk/ui/kis_resource_mediator.h b/chalk/ui/kis_resource_mediator.h new file mode 100644 index 00000000..b224d25c --- /dev/null +++ b/chalk/ui/kis_resource_mediator.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2003 Patrick Julien <freak@codepimps.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_RESOURCE_MEDIATOR_H_ +#define KIS_RESOURCE_MEDIATOR_H_ + +#include <tqobject.h> +#include <tqmap.h> +#include <tqwidget.h> + +class KoIconItem; +class KisItemChooser; +class KisIconItem; +class KisResource; +class KisResourceServerBase; + +/** + * A resource mediator manages access to resources like + * gradients. brushes, patterns and palettes. + * For every view, a new resource mediator is created for every + * resource type. + */ +class KisResourceMediator : public TQObject { + Q_OBJECT + TQ_OBJECT + typedef TQObject super; + +public: + KisResourceMediator(KisItemChooser *chooser, + TQObject *tqparent = 0, + const char *name = 0); + virtual ~KisResourceMediator(); + +public: + void connectServer(KisResourceServerBase* rServer); + KisResource *currentResource() const; + KisIconItem *itemFor(KisResource *r) const; + KisResource *resourceFor(KoIconItem *item) const; + KisResource *resourceFor(KisIconItem *item) const; + TQWidget *chooserWidget() const; + +public slots: + + void setActiveItem(KoIconItem *item); + +signals: + void activatedResource(KisResource *r); + +private slots: + void rServerAddedResource(KisResource *resource); + +private: + KisItemChooser *m_chooser; + TQMap<KisResource*, KisIconItem*> m_items; + KoIconItem *m_activeItem; +}; + +#endif // KIS_RESOURCE_MEDIATOR_H_ + diff --git a/chalk/ui/kis_resourceserver.cc b/chalk/ui/kis_resourceserver.cc new file mode 100644 index 00000000..d464e1bc --- /dev/null +++ b/chalk/ui/kis_resourceserver.cc @@ -0,0 +1,199 @@ +/* + * kis_resourceserver.cc - part of KImageShop + * + * Copyright (c) 1999 Matthias Elter <elter@kde.org> + * Copyright (c) 2003 Patrick Julien <freak@codepimps.org> + * Copyright (c) 2005 Sven Langkamp <longamp@reallygood.de> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include <tqfileinfo.h> +#include <tqstringlist.h> +#include <tqthread.h> +#include <tqdir.h> + +#include <kdebug.h> +#include <kglobal.h> +#include <kstandarddirs.h> +#include <kinstance.h> + +#include "kis_resource.h" +#include "kis_factory.h" +#include "kis_generic_registry.h" +#include "kis_resourceserver.h" +#include "kis_brush.h" +#include "kis_imagepipe_brush.h" +#include "kis_gradient.h" +#include "kis_pattern.h" +#include "kis_palette.h" +#include <kogradientmanager.h> + +KisResourceServerBase::KisResourceServerBase(TQString type) + : m_type(type), m_loaded(false) +{ +} + +KisResourceServerBase::~KisResourceServerBase() +{ +} + +void KisResourceServerBase::loadResources(TQStringList filenames) +{ + TQStringList uniqueFiles; + + while( !filenames.empty() ) + { + + TQString front = *filenames.begin(); + filenames.pop_front(); + + TQString fname = TQFileInfo(front).fileName(); + //ebug() << "Loading " << fname << "\n"; + // XXX: Don't load resources with the same filename. Actually, we should look inside + // the resource to find out whether they are really the same, but for now this + // will prevent the same brush etc. showing up twice. + if (uniqueFiles.empty() || uniqueFiles.tqfind(fname) == uniqueFiles.end()) { + uniqueFiles.append(fname); + KisResource *resource; + resource = createResource(front); + if(resource->load() && resource->valid()) + { + m_resources.append(resource); + Q_CHECK_PTR(resource); + emit resourceAdded(resource); + } + else { + delete resource; + } + } + } + m_loaded = true; +} + +TQValueList<KisResource*> KisResourceServerBase::resources() +{ + if(!m_loaded) { + return TQValueList<KisResource*>(); + } + + return m_resources; +} + +void KisResourceServerBase::addResource(KisResource* resource) +{ + if (!resource->valid()) { + kdWarning(41001) << "Tried to add an invalid resource!" << endl; + return; + } + + m_resources.append(resource); + emit resourceAdded(resource); +} + + +class ResourceLoaderThread : public TQThread { + +public: + + ResourceLoaderThread(KisResourceServerBase * server, TQStringList files) + : TQThread() + , m_server(server) + , m_fileNames( files ) + { + } + + + void run() + { + m_server->loadResources(m_fileNames); + } + +private: + + KisResourceServerBase * m_server; + TQStringList m_fileNames; + +}; + +TQStringList getFileNames( TQString extensions, TQString type ) +{ + TQStringList extensionList = TQStringList::split(":", extensions); + TQStringList fileNames; + + TQStringList::Iterator it; + for ( it = extensionList.begin(); it != extensionList.end(); ++it ) { + TQString s = (*it); + fileNames += KisFactory::instance()->dirs()->findAllResources(type.ascii(), (*it)); + } + return fileNames; +} + + +KisResourceServerRegistry *KisResourceServerRegistry::m_singleton = 0; + +KisResourceServerRegistry::KisResourceServerRegistry() +{ + + KisResourceServer<KisBrush>* brushServer = new KisResourceServer<KisBrush>("kis_brushes"); + ResourceLoaderThread t1 (brushServer, getFileNames( "*.gbr","kis_brushes" )); + t1.start(); + + KisResourceServer<KisImagePipeBrush>* imagePipeBrushServer = new KisResourceServer<KisImagePipeBrush>("kis_brushes"); + ResourceLoaderThread t2 (imagePipeBrushServer, getFileNames( "*.gih", "kis_brushes")); + t2.start(); + + KisResourceServer<KisPattern>* patternServer = new KisResourceServer<KisPattern>("kis_patterns"); + ResourceLoaderThread t3 (patternServer, getFileNames("*.pat", "kis_patterns")); + t3.start(); + + KisResourceServer<KisGradient>* gradientServer = new KisResourceServer<KisGradient>("kis_gradients"); + ResourceLoaderThread t4 (gradientServer, getFileNames(KoGradientManager::filters().join( ":" ), "kis_gradients")); + t4.start(); + + + KisResourceServer<KisPalette>* paletteServer = new KisResourceServer<KisPalette>("kis_palettes"); + ResourceLoaderThread t5 (paletteServer, getFileNames("*.gpl:*.pal:*.act", "kis_palettes") ); + t5.start(); + + t1.wait(); + t2.wait(); + t3.wait(); + t4.wait(); + t5.wait(); + + add( KisID( "BrushServer", ""), brushServer ); + add( KisID( "ImagePipeBrushServer", ""), imagePipeBrushServer ); + add( KisID( "PatternServer", ""), patternServer ); + add( KisID( "GradientServer", ""), gradientServer ); + add( KisID( "PaletteServer", ""), paletteServer ); + +} + +KisResourceServerRegistry::~KisResourceServerRegistry() +{ +} + +KisResourceServerRegistry* KisResourceServerRegistry::instance() +{ + if(KisResourceServerRegistry::m_singleton == 0) + { + KisResourceServerRegistry::m_singleton = new KisResourceServerRegistry(); + } + return KisResourceServerRegistry::m_singleton; +} + + +#include "kis_resourceserver.moc" + diff --git a/chalk/ui/kis_resourceserver.h b/chalk/ui/kis_resourceserver.h new file mode 100644 index 00000000..ab3de04e --- /dev/null +++ b/chalk/ui/kis_resourceserver.h @@ -0,0 +1,91 @@ +/* + * kis_resourceserver.h - part of KImageShop + * + * Copyright (c) 1999 Matthias Elter <elter@kde.org> + * Copyright (c) 2003 Patrick Julien <freak@codepimps.org> + * Copyright (c) 2005 Sven Langkamp <longamp@reallygood.de> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_RESOURCESERVER_H_ +#define KIS_RESOURCESERVER_H_ + +#include <tqstring.h> +#include <tqstringlist.h> + +#include "kis_generic_registry.h" + +class KisResource; + +class KisResourceServerBase : public TQObject { + Q_OBJECT + TQ_OBJECT +public: + KisResourceServerBase(TQString type); + virtual ~KisResourceServerBase(); + + void loadResources(TQStringList filenames); + /// Adds an already loaded resource to the server + void addResource(KisResource* resource); + TQValueList<KisResource*> resources(); + TQString type() { return m_type; }; + +signals: + void resourceAdded(KisResource*); + +protected: + virtual KisResource* createResource( TQString filename ) = 0; + +private: + TQValueList<KisResource*> m_resources; + TQString m_type; + + bool m_loaded; + +}; + + +template <class T> class KisResourceServer : public KisResourceServerBase { + typedef KisResourceServerBase super; + +public: + KisResourceServer(TQString type) :super( type ) {} + virtual ~KisResourceServer(){} + +private: + KisResource* createResource( TQString filename ){return new T(filename);} +}; + + + + +class KisResourceServerRegistry : public KisGenericRegistry<KisResourceServerBase*> +{ + +public: + virtual ~KisResourceServerRegistry(); + + static KisResourceServerRegistry* instance(); + +private: + KisResourceServerRegistry(); + KisResourceServerRegistry(const KisResourceServerRegistry&); + KisResourceServerRegistry operator=(const KisResourceServerRegistry&); + + static KisResourceServerRegistry *m_singleton; +}; + + +#endif // KIS_RESOURCESERVER_H_ diff --git a/chalk/ui/kis_ruler.cc b/chalk/ui/kis_ruler.cc new file mode 100644 index 00000000..6b0eea80 --- /dev/null +++ b/chalk/ui/kis_ruler.cc @@ -0,0 +1,367 @@ +/* + * Kivio - Visual Modelling and Flowcharting + * Copyright (C) 2000-2001 theKompany.com & Dave Marotti + * Copyright (C) 2002 Patrick Julien <freak@codepimps.org> + * + * 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 2 + * of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include <tqpainter.h> +#include <tqstyle.h> + +#include "kdebug.h" + +#include "kis_ruler.h" + +#define MARKER_WIDTH 1 +#define MARKER_HEIGHT RULER_THICKNESS + +const char *KisRuler::m_nums[] = { + "70 7 2 1", + " c Black", + "X c None", + "XX XXXXXX XXXX XXXX XXXXXX XXX XXXX XXX XXX XXXX XX", + "X XXX XXXX XXX XXX XX XXX XXXX XXX XXXXXXX XXXXXXXXX XX XXX XX XXX X", + "X XXX XXXXX XXXXXXX XXXXXX XXX X XXX XXXXXX XXXXXXXXX XXX XXX XX XXX X", + "X XXX XXXXX XXXXX XXXXX XXX XX XXX XXX XXXXXX XXXX XXXX X", + "X XXX XXXXX XXXX XXXXXXXXX XX XXXXXX XX XXX XXXX XXXX XXX XXXXXX X", + "X XXX XXXXX XXX XXXXXX XXX XXXXX XXXXXXX XX XXX XXXX XXXX XXX XXXXX XX", + "XX XXXXXX XXX XXX XXXXXX XXX XXXX XXXXX XXXXX XXXX XXX" +}; + +KisRuler::KisRuler(Qt::Orientation o, TQWidget *tqparent, const char *name) : super(tqparent, name, WRepaintNoErase | WResizeNoErase), m_pixmapNums(m_nums) +{ + setBackgroundMode(NoBackground); + setFrameStyle(Box | Sunken); + setLineWidth(1); + setMidLineWidth(0); + m_orientation = o; + m_unit = KoUnit::U_PT; + m_zoom = 1.0; + m_firstVisible = 0; + m_pixmapBuffer = 0; + m_currentPosition = -1; + + if (m_orientation == Qt::Horizontal) { + setFixedHeight(RULER_THICKNESS); + initMarker(MARKER_WIDTH, MARKER_HEIGHT); + } else { + setFixedWidth(RULER_THICKNESS); + initMarker(MARKER_HEIGHT, MARKER_WIDTH); + } +} + +KisRuler::~KisRuler() +{ + delete m_pixmapBuffer; +} + +void KisRuler::initMarker(TQ_INT32 w, TQ_INT32 h) +{ + TQPainter p; + + m_pixmapMarker.resize(w, h); + p.begin(&m_pixmapMarker); + p.setPen(blue); + p.eraseRect(0, 0, w, h); + p.drawLine(0, 0, w - 1, h - 1); + p.end(); +} + +void KisRuler::recalculateSize() +{ + TQ_INT32 w; + TQ_INT32 h; + + if (m_pixmapBuffer) { + delete m_pixmapBuffer; + m_pixmapBuffer = 0; + } + + if (m_orientation == Qt::Horizontal) { + w = width(); + h = RULER_THICKNESS; + } else { + w = RULER_THICKNESS; + h = height(); + } + + m_pixmapBuffer = new TQPixmap(w, h); + Q_CHECK_PTR(m_pixmapBuffer); + + drawRuler(); + updatePointer(m_currentPosition, m_currentPosition); +} + +KoUnit::Unit KisRuler::unit() const +{ + return m_unit; +} + +void KisRuler::setUnit(KoUnit::Unit u) +{ + m_unit = u; + drawRuler(); + updatePointer(m_currentPosition, m_currentPosition); + update(); +} + +void KisRuler::setZoom(double zoom) +{ + m_zoom = zoom; + recalculateSize(); + drawRuler(); + updatePointer(m_currentPosition, m_currentPosition); + update(); +} + +void KisRuler::updatePointer(TQ_INT32 x, TQ_INT32 y) +{ + if (m_pixmapBuffer) { + if (m_orientation == Qt::Horizontal) { + if (m_currentPosition != -1) + tqrepaint(m_currentPosition, 1, MARKER_WIDTH, MARKER_HEIGHT); + + if (x != -1) { + bitBlt(this, x, 1, &m_pixmapMarker, 0, 0, MARKER_WIDTH, MARKER_HEIGHT); + m_currentPosition = x; + } + } else { + if (m_currentPosition != -1) + tqrepaint(1, m_currentPosition, MARKER_HEIGHT, MARKER_WIDTH); + + if (y != -1) { + bitBlt(this, 1, y, &m_pixmapMarker, 0, 0, MARKER_HEIGHT, MARKER_WIDTH); + m_currentPosition = y; + } + } + } +} + +void KisRuler::updateVisibleArea(TQ_INT32 xpos, TQ_INT32 ypos) +{ + if (m_orientation == Qt::Horizontal) + m_firstVisible = xpos; + else + m_firstVisible = ypos; + + drawRuler(); + update(); + updatePointer(m_currentPosition, m_currentPosition); +} + +void KisRuler::paintEvent(TQPaintEvent *e) +{ + if (m_pixmapBuffer) { + const TQRect& rect = e->rect(); + + bitBlt(this, rect.topLeft(), m_pixmapBuffer, rect); + super::paintEvent(e); + } +} + +void KisRuler::drawRuler() +{ + TQPainter p; + TQString buf; + TQ_INT32 st1 = 0; + TQ_INT32 st2 = 0; + TQ_INT32 st3 = 0; + TQ_INT32 st4 = 0; + + if (!m_pixmapBuffer) + return; + + p.begin(m_pixmapBuffer); + p.setPen(tqcolorGroup().text()); + p.setBackgroundColor(tqcolorGroup().base()); + p.eraseRect(0, 0, m_pixmapBuffer->width(), m_pixmapBuffer->height()); + + switch (m_unit) { + case KoUnit::U_PT: + case KoUnit::U_MM: + case KoUnit::U_DD: + case KoUnit::U_CC: + st1 = 1; + st2 = 5; + st3 = 10; + st4 = 25; + break; + case KoUnit::U_CM: + case KoUnit::U_PI: + case KoUnit::U_INCH: + default: + st1 = 1; + st2 = 2; + st3 = 5; + st4 = 10; + } + + bool s1 = KoUnit::fromUserValue(st1, m_unit) * m_zoom > 3.0; + bool s2 = KoUnit::fromUserValue(st2, m_unit) * m_zoom > 3.0; + bool s3 = KoUnit::fromUserValue(st3, m_unit) * m_zoom > 3.0; + bool s4 = KoUnit::fromUserValue(st4, m_unit) * m_zoom > 3.0; + + float cx = KoUnit::fromUserValue(100, m_unit) / m_zoom; + TQ_INT32 step = tqRound(cx); + + if (step < 5) { + step = 1; + } else if (step < 10) { + step = 5; + } else if (step < 25) { + step = 10; + } else if (step < 50) { + step = 25; + } else if (step < 100) { + step = 50; + } else if (step < 250) { + step = 100; + } else if (step < 500) { + step = 250; + } else if (step < 1000) { + step = 500; + } else if (step < 2500) { + step = 1000; + } else if (step < 5000) { + step = 2500; + } else if (step < 10000) { + step = 5000; + } else if (step < 25000) { + step = 10000; + } else if (step < 50000) { + step = 25000; + } else if (step < 100000) { + step = 50000; + } else { + step = 100000; + } + + TQ_INT32 start = (TQ_INT32)(KoUnit::fromUserValue(m_firstVisible, m_unit) / m_zoom); + TQ_INT32 pos = 0; + + if (m_orientation == Qt::Horizontal) { + do { + pos = (TQ_INT32)(KoUnit::fromUserValue(start, m_unit) * m_zoom - m_firstVisible); + + if (!s3 && s4 && start % st4 == 0) + p.drawLine(pos, RULER_THICKNESS - 9, pos, RULER_THICKNESS); + + if (s3 && start % st3 == 0) + p.drawLine(pos, RULER_THICKNESS - 9, pos, RULER_THICKNESS); + + if (s2 && start % st2 == 0) + p.drawLine(pos, RULER_THICKNESS - 7, pos, RULER_THICKNESS); + + if (s1 && start % st1 == 0) + p.drawLine(pos, RULER_THICKNESS - 5, pos, RULER_THICKNESS); + + if (start % step == 0) { + buf.setNum(TQABS(start)); + drawNums(&p, pos, 4, buf, true); + } + + start++; + } while (pos < m_pixmapBuffer->width()); + } else { + do { + pos = (TQ_INT32)(KoUnit::fromUserValue(start, m_unit) * m_zoom - m_firstVisible); + + if (!s3 && s4 && start % st4 == 0) + p.drawLine(RULER_THICKNESS - 9, pos, RULER_THICKNESS, pos); + + if (s3 && start % st3 == 0) + p.drawLine(RULER_THICKNESS - 9, pos, RULER_THICKNESS, pos); + + if (s2 && start % st2 == 0) + p.drawLine(RULER_THICKNESS - 7, pos, RULER_THICKNESS, pos); + + if (s1 && start % st1 == 0) + p.drawLine(RULER_THICKNESS - 5, pos, RULER_THICKNESS, pos); + + if (start % step == 0) { + buf.setNum(TQABS(start)); + drawNums(&p, 4, pos, buf, false); + } + + start++; + } while (pos < m_pixmapBuffer->height()); + } + + p.end(); +} + +void KisRuler::resizeEvent(TQResizeEvent *) +{ + recalculateSize(); +} + +void KisRuler::styleChange(TQStyle& oldStyle) +{ + Q_UNUSED(oldStyle); + updateGeometry(); + drawRuler(); +} + +void KisRuler::paletteChange(const TQPalette& oldPalette) +{ + Q_UNUSED(oldPalette); + drawRuler(); +} + +void KisRuler::show() +{ + if (m_orientation == Qt::Horizontal) { + setFixedHeight(RULER_THICKNESS); + initMarker(MARKER_WIDTH, MARKER_HEIGHT); + } else { + setFixedWidth(RULER_THICKNESS); + initMarker(MARKER_HEIGHT, MARKER_WIDTH); + } + + super::show(); +} + +void KisRuler::hide() +{ + /* + if (m_orientation == Qt::Horizontal) + setFixedHeight(1); + else + setFixedWidth(1); + */ + super::hide(); +} + +void KisRuler::drawNums(TQPainter *p, TQ_INT32 x, TQ_INT32 y, TQString& num, bool orientationHoriz) +{ + if (orientationHoriz) + x -= 7; + else + y -= 8; + + for (TQ_UINT32 k = 0; k < num.length(); k++) { + TQ_INT32 st = num.at(k).digitValue() * 7; + + p->drawPixmap(x, y, m_pixmapNums, st, 0, 7, 7); + + if (orientationHoriz) + x += 7; + else + y += 8; + } +} + +#include "kis_ruler.moc" + diff --git a/chalk/ui/kis_ruler.h b/chalk/ui/kis_ruler.h new file mode 100644 index 00000000..6c8dd46d --- /dev/null +++ b/chalk/ui/kis_ruler.h @@ -0,0 +1,81 @@ +/* + * Kivio - Visual Modelling and Flowcharting + * Copyright (C) 2000-2001 theKompany.com & Dave Marotti + * Copyright (C) 2002 Patrick Julien <freak@codepimps.org> + * + * 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 2 + * of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_RULER_H_ +#define KIS_RULER_H_ + +#include <tqframe.h> +#include <tqpixmap.h> +#include <KoUnit.h> + +// XXX: Make this look more like the KOffice ruler -- the KOffice +// ruler is not quite suited to Chalk. Also: start units with 0, +// print every 100 units. + +#define RULER_THICKNESS 20 + +class TQPainter; + +class KisRuler : public TQFrame { + Q_OBJECT + TQ_OBJECT + typedef TQFrame super; + +public: + KisRuler(Qt::Orientation, TQWidget *tqparent = 0, const char *name = 0); + virtual ~KisRuler(); + +public: + KoUnit::Unit unit() const; + +public slots: + void setZoom(double zoom); + void updatePointer(TQ_INT32 x, TQ_INT32 y); + void updateVisibleArea(TQ_INT32 xpos, TQ_INT32 ypos); + void setUnit(KoUnit::Unit u); + void hide(); + void show(); + +protected: + virtual void paintEvent(TQPaintEvent *e); + virtual void resizeEvent(TQResizeEvent *e); + virtual void styleChange(TQStyle& oldStyle); + virtual void paletteChange(const TQPalette& oldPalette); + + void recalculateSize(); + void drawRuler(); + void initMarker(TQ_INT32 w, TQ_INT32 h); + void drawNums(TQPainter *gc, TQ_INT32 x, TQ_INT32 y, TQString& num, bool orientationHoriz); + +private: + KoUnit::Unit m_unit; + Qt::Orientation m_orientation; + TQ_INT32 m_firstVisible; + TQ_INT32 m_currentPosition; + TQPixmap *m_pixmapBuffer; + TQPixmap m_pixmapMarker; + TQPixmap m_pixmapNums; + double m_zoom; + +private: + static const char *m_nums[]; +}; + +#endif // KIS_RULER_H_ + diff --git a/chalk/ui/kis_save_visitor.h b/chalk/ui/kis_save_visitor.h new file mode 100644 index 00000000..ce668a53 --- /dev/null +++ b/chalk/ui/kis_save_visitor.h @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2002 Patrick Julien <freak@codepimps.org> + * Copyright (c) 2005 Casper Boemann <cbr@boemann.dk> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_SAVE_VISITOR_H_ +#define KIS_SAVE_VISITOR_H_ + +#include <tqrect.h> +#include "kis_types.h" +#include "kis_layer_visitor.h" +#include "kis_image.h" +#include "kis_layer.h" +#include "kis_paint_layer.h" +#include "kis_group_layer.h" + +class KisSaveVisitor : public KisLayerVisitor { +public: + KisSaveVisitor(KisImageSP img, KoStore *store, TQ_UINT32 &count) : + KisLayerVisitor(), + m_count(count) + { + m_external = false; + m_img = img; + m_store = store; + } + +public: + void setExternalUri(TQString &uri) + { + m_external = true; + m_uri = uri; + } + + virtual bool visit(KisPaintLayer *layer) + { + //connect(*layer->paintDevice(), TQT_SIGNAL(ioProgress(TQ_INT8)), m_img, TQT_SLOT(slotIOProgress(TQ_INT8))); + + TQString location = m_external ? TQString() : m_uri; + location += m_img->name() + TQString("/layers/layer%1").tqarg(m_count); + + // Layer data + if (m_store->open(location)) { + if (!layer->paintDevice()->write(m_store)) { + layer->paintDevice()->disconnect(); + m_store->close(); + //IODone(); + return false; + } + + m_store->close(); + } + + if (layer->paintDevice()->colorSpace()->getProfile()) { + KisAnnotationSP annotation = layer->paintDevice()->colorSpace()->getProfile()->annotation(); + + if (annotation) { + // save layer profile + location = m_external ? TQString() : m_uri; + location += m_img->name() + TQString("/layers/layer%1").tqarg(m_count) + ".icc"; + + if (m_store->open(location)) { + m_store->write(annotation->annotation()); + m_store->close(); + } + } + } + + if (layer->hasMask()) { + KisPaintDeviceSP tqmask = layer->getMask(); + + if (tqmask) { + // save layer profile + location = m_external ? TQString() : m_uri; + location += m_img->name() + TQString("/layers/layer%1").tqarg(m_count) + ".tqmask"; + + if (m_store->open(location)) { + if (!tqmask->write(m_store)) { + tqmask->disconnect(); + m_store->close(); + return false; + } + + m_store->close(); + } + } + } + + m_count++; + return true; + } + + virtual bool visit(KisGroupLayer *layer) + { + KisSaveVisitor visitor(m_img, m_store, m_count); + + if(m_external) + visitor.setExternalUri(m_uri); + + KisLayerSP child = layer->firstChild(); + + while(child) + { + child->accept(visitor); + child = child->nextSibling(); + } + return true; + } + + virtual bool visit(KisPartLayer *) + { + return true; + } + + virtual bool visit(KisAdjustmentLayer* layer) + { + + if (layer->selection()) { + TQString location = m_external ? TQString() : m_uri; + location += m_img->name() + TQString("/layers/layer%1").tqarg(m_count) + ".selection"; + + // Layer data + if (m_store->open(location)) { + if (!layer->selection()->write(m_store)) { + layer->selection()->disconnect(); + m_store->close(); + //IODone(); + return false; + } + m_store->close(); + } + } + + if (layer->filter()) { + TQString location = m_external ? TQString() : m_uri; + location = m_external ? TQString() : m_uri; + location += m_img->name() + TQString("/layers/layer%1").tqarg(m_count) + ".filterconfig"; + + if (m_store->open(location)) { + TQString s = layer->filter()->toString(); + m_store->write(s.utf8(), tqstrlen(s.utf8())); + m_store->close(); + } + } + m_count++; + return true; + } + +private: + KisImageSP m_img; + KoStore *m_store; + bool m_external; + TQString m_uri; + TQ_UINT32 &m_count; +}; + +#endif // KIS_SAVE_VISITOR_H_ + diff --git a/chalk/ui/kis_savexml_visitor.h b/chalk/ui/kis_savexml_visitor.h new file mode 100644 index 00000000..52c0dc80 --- /dev/null +++ b/chalk/ui/kis_savexml_visitor.h @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2002 Patrick Julien <freak@codepimps.org> + * Copyright (c) 2005 Casper Boemann <cbr@boemann.dk> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_SAVEXML_VISITOR_H_ +#define KIS_SAVEXML_VISITOR_H_ + +#include <tqrect.h> + +#include "kis_adjustment_layer.h" +#include "kis_exif_info.h" +#include "kis_group_layer.h" +#include "kis_image.h" +#include "kis_layer.h" +#include "kis_layer_visitor.h" +#include "kis_paint_layer.h" +#include "kis_types.h" + +class KisSaveXmlVisitor : public KisLayerVisitor { +public: + KisSaveXmlVisitor(TQDomDocument doc, TQDomElement element, TQ_UINT32 &count, bool root=false) : + KisLayerVisitor(), + m_doc(doc), + m_count(count), + m_root(root) + { + m_elem = element; + } + +public: + virtual bool visit(KisPaintLayer *layer) + { + TQDomElement layerElement = m_doc.createElement("layer"); + + layerElement.setAttribute("name", layer->name()); + layerElement.setAttribute("x", layer->x()); + layerElement.setAttribute("y", layer->y()); + layerElement.setAttribute("opacity", layer->opacity()); + layerElement.setAttribute("compositeop", layer->compositeOp().id().id()); + layerElement.setAttribute("visible", layer->visible()); + layerElement.setAttribute("locked", layer->locked()); + layerElement.setAttribute("layertype", "paintlayer"); + layerElement.setAttribute("filename", TQString("layer%1").tqarg(m_count)); + layerElement.setAttribute("colorspacename", layer->paintDevice()->colorSpace()->id().id()); + layerElement.setAttribute("hastqmask", layer->hasMask()); + m_elem.appendChild(layerElement); + + if(layer->paintDevice()->hasExifInfo()) + { + TQDomElement exifElmt = layer->paintDevice()->exifInfo()->save(m_doc); + layerElement.appendChild(exifElmt); + } + m_count++; + return true; + } + + virtual bool visit(KisGroupLayer *layer) + { + TQDomElement layerElement; + + if(m_root) // if this is the root we fake so not to save it + layerElement = m_elem; + else + { + layerElement = m_doc.createElement("layer"); + + layerElement.setAttribute("name", layer->name()); + layerElement.setAttribute("x", layer->x()); + layerElement.setAttribute("y", layer->y()); + layerElement.setAttribute("opacity", layer->opacity()); + layerElement.setAttribute("compositeop", layer->compositeOp().id().id()); + layerElement.setAttribute("visible", layer->visible()); + layerElement.setAttribute("locked", layer->locked()); + layerElement.setAttribute("layertype", "grouplayer"); + + m_elem.appendChild(layerElement); + } + + TQDomElement elem = m_doc.createElement("LAYERS"); + + layerElement.appendChild(elem); + + KisSaveXmlVisitor visitor(m_doc, elem, m_count); + + KisLayerSP child = layer->firstChild(); + + while(child) + { + child->accept(visitor); + child = child->nextSibling(); + } + return true; + } + + virtual bool visit(KisPartLayer* layer) + { + bool ok = layer->saveToXML(m_doc, m_elem); + return ok; + } + + virtual bool visit(KisAdjustmentLayer* layer) + { + TQDomElement layerElement = m_doc.createElement("layer"); + + layerElement.setAttribute("name", layer->name()); + layerElement.setAttribute("filtername", layer->filter()->name()); + layerElement.setAttribute("filterversion", layer->filter()->version()); + layerElement.setAttribute("opacity", layer->opacity()); + layerElement.setAttribute("compositeop", layer->compositeOp().id().id()); + layerElement.setAttribute("visible", layer->visible()); + layerElement.setAttribute("locked", layer->locked()); + layerElement.setAttribute("layertype", "adjustmentlayer"); + layerElement.setAttribute("filename", TQString("layer%1").tqarg(m_count)); + layerElement.setAttribute("x", layer->x()); + layerElement.setAttribute("y", layer->y()); + m_elem.appendChild(layerElement); + + m_count++; + return true; + } + +private: + TQDomDocument m_doc; + TQDomElement m_elem; + TQ_UINT32 &m_count; + bool m_root; +}; + +#endif // KIS_SAVEXML_VISITOR_H_ + diff --git a/chalk/ui/kis_selection_manager.cc b/chalk/ui/kis_selection_manager.cc new file mode 100644 index 00000000..3caba5e7 --- /dev/null +++ b/chalk/ui/kis_selection_manager.cc @@ -0,0 +1,1643 @@ +/* + * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <tqobject.h> +#include <tqapplication.h> +#include <tqclipboard.h> +#include <tqcolor.h> +#include <tqcursor.h> + +#include <kdebug.h> +#include <kaction.h> +#include <klocale.h> +#include <kstdaction.h> + +#include <KoDocument.h> +#include <KoMainWindow.h> +#include <KoQueryTrader.h> + +#include "kis_cursor.h" +#include "kis_part_layer.h" +#include "kis_adjustment_layer.h" +#include "kis_clipboard.h" +#include "kis_types.h" +#include "kis_view.h" +#include "kis_doc.h" +#include "kis_image.h" +#include "kis_selection.h" +#include "kis_selection_manager.h" +#include "kis_painter.h" +#include "kis_iterators_pixel.h" +#include "kis_iteratorpixeltrait.h" +#include "kis_layer.h" +#include "kis_group_layer.h" +#include "kis_paint_layer.h" +#include "kis_paint_device.h" +#include "kis_channelinfo.h" +#include "kis_dlg_apply_profile.h" +#include "kis_config.h" +#include "kis_debug_areas.h" +#include "kis_transaction.h" +#include "kis_undo_adapter.h" +#include "kis_selected_transaction.h" +#include "kis_convolution_painter.h" +#include "kis_integer_maths.h" +#include "kis_fill_painter.h" +#include "kis_canvas.h" + +KisSelectionManager::KisSelectionManager(KisView * tqparent, KisDoc * doc) + : m_parent(tqparent), + m_doc(doc), + m_copy(0), + m_cut(0), + m_paste(0), + m_pasteNew(0), + m_cutToNewLayer(0), + m_selectAll(0), + m_deselect(0), + m_clear(0), + m_reselect(0), + m_invert(0), + m_toNewLayer(0), + m_feather(0), + m_border(0), + m_expand(0), + m_smooth(0), + m_contract(0), + m_similar(0), + m_transform(0), + m_load(0), + m_save(0), + m_fillForegroundColor(0), + m_fillBackgroundColor(0), + m_fillPattern(0) +{ + m_pluginActions.setAutoDelete(true); + m_clipboard = KisClipboard::instance(); +} + +KisSelectionManager::~KisSelectionManager() +{ + m_pluginActions.clear(); +} + + +void KisSelectionManager::setup(KActionCollection * collection) +{ + // XXX: setup shortcuts! + + m_cut = KStdAction::cut(this, + TQT_SLOT(cut()), + collection, + "cut"); + + m_copy = KStdAction::copy(this, + TQT_SLOT(copy()), + collection, + "copy"); + + m_paste = KStdAction::paste(this, + TQT_SLOT(paste()), + collection, + "paste"); + + m_pasteNew = new KAction(i18n("Paste into &New Image"), + 0, 0, + this, TQT_SLOT(pasteNew()), + collection, + "paste_new"); + + + m_selectAll = KStdAction::selectAll(this, + TQT_SLOT(selectAll()), + collection, + "select_all"); + + m_deselect = KStdAction::deselect(this, + TQT_SLOT(deselect()), + collection, + "deselect"); + + + m_clear = KStdAction::clear(this, + TQT_SLOT(clear()), + collection, + "clear"); + + m_reselect = new KAction(i18n("&Reselect"), + 0, "Ctrl+Shift+D", + this, TQT_SLOT(reselect()), + collection, "reselect"); + + m_invert = new KAction(i18n("&Invert"), + 0, "Ctrl+I", + this, TQT_SLOT(invert()), + collection, "invert"); + + + m_toNewLayer = new KAction(i18n("Copy Selection to New Layer"), + 0, "Ctrl+J", + this, TQT_SLOT(copySelectionToNewLayer()), + collection, "copy_selection_to_new_layer"); + + + m_cutToNewLayer = new KAction(i18n("Cut Selection to New Layer"), + 0, "Ctrl+Shift+J", + this, TQT_SLOT(cutToNewLayer()), + collection, "cut_selection_to_new_layer"); + + m_feather = new KAction(i18n("Feather"), + 0, "Ctrl+Alt+D", + this, TQT_SLOT(feather()), + collection, "feather"); + + m_fillForegroundColor = new KAction(i18n("Fill with Foreground Color"), + "Alt+backspace", this, + TQT_SLOT(fillForegroundColor()), + collection, + "fill_selection_foreground_color"); + m_fillBackgroundColor = new KAction(i18n("Fill with Background Color"), + "backspace", this, + TQT_SLOT(fillBackgroundColor()), + collection, + "fill_selection_background_color"); + m_fillPattern = new KAction(i18n("Fill with Pattern"), + 0, this, + TQT_SLOT(fillPattern()), + collection, + "fill_selection_pattern"); + + m_toggleDisplaySelection = new KToggleAction(i18n("Display Selection"), "Ctrl+h", this, TQT_SLOT(toggleDisplaySelection()), collection, "toggle_display_selection"); + m_toggleDisplaySelection->setCheckedState(KGuiItem(i18n("Hide Selection"))); + m_toggleDisplaySelection->setChecked(true); + + m_border = + new KAction(i18n("Border..."), + 0, 0, + this, TQT_SLOT(border()), + collection, "border"); + m_expand = + new KAction(i18n("Expand..."), + 0, 0, + this, TQT_SLOT(expand()), + collection, "expand"); + + m_smooth = + new KAction(i18n("Smooth..."), + 0, 0, + this, TQT_SLOT(smooth()), + collection, "smooth"); + + + m_contract = + new KAction(i18n("Contract..."), + 0, 0, + this, TQT_SLOT(contract()), + collection, "contract"); + m_similar = + new KAction(i18n("Similar"), + 0, 0, + this, TQT_SLOT(similar()), + collection, "similar"); + + + m_transform + = new KAction(i18n("Transform..."), + 0, 0, + this, TQT_SLOT(transform()), + collection, "transform_selection"); + + +// m_load +// = new KAction(i18n("Load..."), +// 0, 0, +// this, TQT_SLOT(load()), +// collection, "load_selection"); +// +// +// m_save +// = new KAction(i18n("Save As..."), +// 0, 0, +// this, TQT_SLOT(save()), +// collection, "save_selection"); + + TQClipboard *cb = TQApplication::tqclipboard(); + connect(cb, TQT_SIGNAL(dataChanged()), TQT_SLOT(clipboardDataChanged())); +} + +void KisSelectionManager::clipboardDataChanged() +{ + updateGUI(); +} + + +void KisSelectionManager::addSelectionAction(KAction * action) +{ + m_pluginActions.append(action); +} + + +void KisSelectionManager::updateGUI() +{ + Q_ASSERT(m_parent); + Q_ASSERT(m_clipboard); + + if (m_parent == 0) { + // "Eek, no tqparent! + return; + } + + if (m_clipboard == 0) { + // Eek, no clipboard! + return; + } + + KisImageSP img = m_parent->currentImg(); + KisLayerSP l = 0; + KisPaintDeviceSP dev = 0; + + bool enable = false; + if (img && img->activeDevice() && img->activeLayer()) { + l = img->activeLayer(); + dev = img->activeDevice(); + + + KisPartLayer * partLayer = dynamic_cast<KisPartLayer*>(l.data()); + KisAdjustmentLayer * adjLayer = dynamic_cast<KisAdjustmentLayer*>(l.data()); + + enable = l && dev&& dev->hasSelection() && !l->locked() && l->visible() && (partLayer==0); + + if(dev && !adjLayer) + m_reselect->setEnabled( dev->selectionDeselected() ); + if (adjLayer) // There's no reselect for adjustment layers + m_reselect->setEnabled(false); + } + + m_cut->setEnabled(enable); + m_cutToNewLayer->setEnabled(enable); + m_selectAll->setEnabled(img != 0); + m_deselect->setEnabled(enable); + m_clear->setEnabled(enable); + m_fillForegroundColor->setEnabled(enable); + m_fillBackgroundColor->setEnabled(enable); + m_fillPattern->setEnabled(enable); + m_invert->setEnabled(enable); + + m_feather->setEnabled(enable); + + m_border->setEnabled(enable); + m_expand->setEnabled(enable); + m_smooth->setEnabled(enable); + m_contract->setEnabled(enable); + m_similar->setEnabled(enable); + m_transform->setEnabled(enable); +// m_load->setEnabled(enable); +// m_save->setEnabled(enable); + + + KAction * a; + for (a = m_pluginActions.first(); a; a = m_pluginActions.next()) { + a->setEnabled(img != 0); + } + + // You can copy from locked layers and paste the clip into a new layer, even when + // the current layer is locked. + enable = false; + if (img && l && dev) { + enable = dev->hasSelection() && l->visible(); + } + + m_copy->setEnabled(enable); + m_paste->setEnabled(img != 0 && m_clipboard->hasClip()); + m_pasteNew->setEnabled(img != 0 && m_clipboard->hasClip()); + m_toNewLayer->setEnabled(enable); + + m_parent->updateStatusBarSelectionLabel(); + +} + +void KisSelectionManager::imgSelectionChanged(KisImageSP img) +{ + if (img == m_parent->currentImg()) { + updateGUI(); + } +} + +void KisSelectionManager::cut() +{ + KisImageSP img = m_parent->currentImg(); + if (!img) return; + + KisPaintDeviceSP dev = img->activeDevice(); + if (!dev) return; + + if (!dev->hasSelection()) return; + + copy(); + + KisSelectedTransaction *t = 0; + + if (img->undo()) { + t = new KisSelectedTransaction(i18n("Cut"), dev); + Q_CHECK_PTR(t); + } + + dev->clearSelection(); + dev->deselect(); + dev->emitSelectionChanged(); + + if (img->undo()) { + img->undoAdapter()->addCommand(t); + } +} + +void KisSelectionManager::copy() +{ + KisImageSP img = m_parent->currentImg(); + if (!img) return; + + KisPaintDeviceSP dev = img->activeDevice(); + if (!dev) return; + + if (!dev->hasSelection()) return; + + KisSelectionSP selection = dev->selection(); + + TQRect r = selection->selectedExactRect(); + + KisPaintDeviceSP clip = new KisPaintDevice(dev->colorSpace(), "clip"); + Q_CHECK_PTR(clip); + + KisColorSpace * cs = clip->colorSpace(); + + // TODO if the source is linked... copy from all linked layers?!? + + // Copy image data + KisPainter gc; + gc.begin(clip); + gc.bitBlt(0, 0, COMPOSITE_COPY, dev, r.x(), r.y(), r.width(), r.height()); + gc.end(); + + // Apply selection tqmask. + + for (TQ_INT32 y = 0; y < r.height(); y++) { + KisHLineIteratorPixel layerIt = clip->createHLineIterator(0, y, r.width(), true); + KisHLineIteratorPixel selectionIt = selection->createHLineIterator(r.x(), r.y() + y, r.width(), false); + + while (!layerIt.isDone()) { + + cs->applyAlphaU8Mask( layerIt.rawData(), selectionIt.rawData(), 1 ); + + + ++layerIt; + ++selectionIt; + } + } + + m_clipboard->setClip(clip); + imgSelectionChanged(m_parent->currentImg()); +} + + +KisLayerSP KisSelectionManager::paste() +{ + KisImageSP img = m_parent->currentImg(); + if (!img) return 0; + + KisPaintDeviceSP clip = m_clipboard->clip(); + + if (clip) { + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + KisPaintLayer *layer = new KisPaintLayer(img, img->nextLayerName() + i18n("(pasted)"), OPACITY_OPAQUE); + Q_CHECK_PTR(layer); + + TQRect r = clip->exactBounds(); + KisPainter gc; + gc.begin(layer->paintDevice()); + gc.bitBlt(0, 0, COMPOSITE_COPY, clip, r.x(), r.y(), r.width(), r.height()); + gc.end(); + + //figure out where to position the clip + KisCanvasController *cc = m_parent->getCanvasController(); + TQPoint center = cc->viewToWindow(TQPoint(cc->kiscanvas()->width()/2, cc->kiscanvas()->height()/2)); + TQPoint bottomright = cc->viewToWindow(TQPoint(cc->kiscanvas()->width(), cc->kiscanvas()->height())); + if(bottomright.x() > img->width()) + center.setX(img->width()/2); + if(bottomright.y() > img->height()) + center.setY(img->height()/2); + center -= TQPoint(r.width()/2, r.height()/2); + layer->setX(center.x()); + layer->setY(center.y()); + +/*XXX CBR have an idea of asking the user if he is about to paste a clip ion another cs than that of + the image if that is what he want rather than silently converting + if (clip->colorSpace != img ->colorSpace()) + if (dlg->exec() == TQDialog::Accepted) + layer->convertTo(img->colorSpace()); +*/ + TQApplication::restoreOverrideCursor(); + if(img->addLayer(layer, img->activeLayer()->tqparent(), img->activeLayer())) + { + return layer; + } else { + return 0; + } + } + return 0; +} + +void KisSelectionManager::pasteNew() +{ + KisPaintDeviceSP clip = m_clipboard->clip(); + if (!clip) return; + + TQRect r = clip->exactBounds(); + if (r.width() < 1 && r.height() < 1) { + // Don't paste empty clips + return; + } + + const TQCString mimetype = KoDocument::readNativeFormatMimeType(); + KoDocumentEntry entry = KoDocumentEntry::queryByMimeType( mimetype ); + KisDoc * doc = (KisDoc*) entry.createDoc(); + + Q_ASSERT(doc->undoAdapter() != 0); + doc->undoAdapter()->setUndo(false); + + KisImageSP img = new KisImage(doc->undoAdapter(), r.width(), r.height(), clip->colorSpace(), "Pasted"); + KisPaintLayer *layer = new KisPaintLayer(img, clip->name(), OPACITY_OPAQUE, clip->colorSpace()); + + KisPainter p(layer->paintDevice()); + p.bitBlt(0, 0, COMPOSITE_COPY, clip, OPACITY_OPAQUE, r.x(), r.y(), r.width(), r.height()); + p.end(); + + img->addLayer(layer, img->rootLayer(), 0); + doc->setCurrentImage(img); + + doc->undoAdapter()->setUndo(true); + + KoMainWindow *win = new KoMainWindow( doc->instance() ); + win->show(); + win->setRootDocument( doc ); +} + +void KisSelectionManager::selectAll() +{ + KisImageSP img = m_parent->currentImg(); + if (!img) return; + + KisPaintDeviceSP dev = img->activeDevice(); + if (!dev) return; + + KisSelectedTransaction * t = 0; + if (img->undo()) t = new KisSelectedTransaction(i18n("Select All"), dev); + Q_CHECK_PTR(t); + + // Make adjustment layers behave better + KisAdjustmentLayer* adj = dynamic_cast<KisAdjustmentLayer*>(img->activeLayer().data()); + if (adj) { + adj->clearSelection(); + adj->selection()->invert(); + } else { + dev->selection()->clear(); + dev->selection()->invert(); + } + dev->setDirty(); + dev->emitSelectionChanged(); + + if (img->undo()) + img->undoAdapter()->addCommand(t); +} + +void KisSelectionManager::deselect() +{ + KisImageSP img = m_parent->currentImg(); + if (!img) return; + + KisPaintDeviceSP dev = img->activeDevice(); + if (!dev) return; + KisSelectedTransaction * t = 0; + if (img->undo()) t = new KisSelectedTransaction(i18n("Deselect"), dev); + Q_CHECK_PTR(t); + + // Make adjustment layers behave almost the same (except no reselect) + KisAdjustmentLayer* adj = dynamic_cast<KisAdjustmentLayer*>(img->activeLayer().data()); + if (adj) { + adj->clearSelection(); + } else { + dev->deselect(); + } + dev->setDirty(); + dev->emitSelectionChanged(); + + if (img->undo()) + img->undoAdapter()->addCommand(t); +} + + +void KisSelectionManager::clear() +{ + KisImageSP img = m_parent->currentImg(); + if (!img) return; + + KisPaintDeviceSP dev = img->activeDevice(); + if (!dev) return; + + if (!dev->hasSelection()) return; + + KisTransaction * t = 0; + + if (img->undo()) { + t = new KisTransaction(i18n("Clear"), dev); + } + + dev->clearSelection(); + dev->setDirty(); + dev->emitSelectionChanged(); + + if (img->undo()) img->undoAdapter()->addCommand(t); +} + +void KisSelectionManager::fill(const KisColor& color, bool fillWithPattern, const TQString& transactionText) +{ + KisImageSP img = m_parent->currentImg(); + if (!img) return; + + KisPaintDeviceSP dev = img->activeDevice(); + if (!dev) return; + + if (!dev->hasSelection()) return; + + KisSelectionSP selection = dev->selection(); + + KisPaintDeviceSP filled = new KisPaintDevice(dev->colorSpace()); + KisFillPainter painter(filled); + + if (fillWithPattern) { + painter.fillRect(0, 0, img->width(), img->height(), + m_parent->currentPattern()); + } else { + painter.fillRect(0, 0, img->width(), img->height(), color); + } + + painter.end(); + + KisPainter painter2(dev); + + if (img->undo()) painter2.beginTransaction(transactionText); + painter2.bltSelection(0, 0, COMPOSITE_OVER, filled, OPACITY_OPAQUE, + 0, 0, img->width(), img->height()); + + dev->setDirty(); + dev->emitSelectionChanged(); + + if (img->undo()) { + img->undoAdapter()->addCommand(painter2.endTransaction()); + } +} + +void KisSelectionManager::fillForegroundColor() +{ + fill(m_parent->fgColor(), false, i18n("Fill with Foreground Color")); +} + +void KisSelectionManager::fillBackgroundColor() +{ + fill(m_parent->bgColor(), false, i18n("Fill with Background Color")); +} + +void KisSelectionManager::fillPattern() +{ + fill(KisColor(), true, i18n("Fill with Pattern")); +} + +void KisSelectionManager::reselect() +{ + KisImageSP img = m_parent->currentImg(); + if (!img) return; + + KisPaintDeviceSP dev = img ->activeDevice(); + if (!dev) return; + + KisSelectedTransaction * t = 0; + if (img->undo()) t = new KisSelectedTransaction(i18n("Reselect"), dev); + Q_CHECK_PTR(t); + + dev->reselect(); // sets hasSelection=true + dev->setDirty(); + dev->emitSelectionChanged(); + + if (img->undo()) + img->undoAdapter()->addCommand(t); +} + + +void KisSelectionManager::invert() +{ + KisImageSP img = m_parent->currentImg(); + if (!img) return; + + KisPaintDeviceSP dev = img->activeDevice(); + if (!dev) return; + + if (dev->hasSelection()) { + KisSelectionSP s = dev->selection(); + + KisSelectedTransaction * t = 0; + if (img->undo()) + { + t = new KisSelectedTransaction(i18n("Invert"), dev); + Q_CHECK_PTR(t); + } + + s->invert(); + dev->setDirty(); + dev->emitSelectionChanged(); + + if (t) { + img->undoAdapter()->addCommand(t); + } + } +} + +void KisSelectionManager::copySelectionToNewLayer() +{ + KisImageSP img = m_parent->currentImg(); + if (!img) return; + + KisPaintDeviceSP dev = img->activeDevice(); + if (!dev) return; + + copy(); + paste(); +} + +void KisSelectionManager::cutToNewLayer() +{ + KisImageSP img = m_parent->currentImg(); + if (!img) return; + + KisPaintDeviceSP dev = img->activeDevice(); + if (!dev) return; + + cut(); + paste(); +} + + +void KisSelectionManager::feather() +{ + KisImageSP img = m_parent->currentImg(); + if (!img) return; + KisPaintDeviceSP dev = img->activeDevice(); + if (!dev) return; + + if (!dev->hasSelection()) { + // activate it, but don't do anything with it + dev->selection(); + return; + } + + KisSelectionSP selection = dev->selection(); + KisSelectedTransaction * t = 0; + if (img->undo()) t = new KisSelectedTransaction(i18n("Feather..."), dev); + Q_CHECK_PTR(t); + + + // XXX: we should let gaussian blur & others influence alpha channels as well + // (on demand of the caller) + + KisConvolutionPainter painter(selection.data()); + + KisKernelSP k = new KisKernel(); + k->width = 3; + k->height = 3; + k->factor = 16; + k->offset = 0; + k->data = new TQ_INT32[9]; + k->data[0] = 1; + k->data[1] = 2; + k->data[2] = 1; + k->data[3] = 2; + k->data[4] = 4; + k->data[5] = 2; + k->data[6] = 1; + k->data[7] = 2; + k->data[8] = 1; + + TQRect rect = selection->selectedRect(); + // Make sure we've got enough space around the edges. + rect = TQRect(rect.x() - 3, rect.y() - 3, rect.width() + 6, rect.height() + 6); + rect &= TQRect(0, 0, img->width(), img->height()); + + painter.applyMatrix(k, rect.x(), rect.y(), rect.width(), rect.height(), BORDER_AVOID, KisChannelInfo::FLAG_ALPHA); + painter.end(); + + dev->setDirty(rect); + dev->emitSelectionChanged(); + + if (img->undo()) + img->undoAdapter()->addCommand(t); + +} + +void KisSelectionManager::toggleDisplaySelection() +{ + m_parent->selectionDisplayToggled(displaySelection()); +} + +bool KisSelectionManager::displaySelection() +{ + return m_toggleDisplaySelection->isChecked(); +} +// XXX: Maybe move these esoteric functions to plugins? +void KisSelectionManager::border() {} +void KisSelectionManager::expand() {} +void KisSelectionManager::contract() {} +void KisSelectionManager::similar() {} +void KisSelectionManager::transform() {} +void KisSelectionManager::load() {} +void KisSelectionManager::save() {} + +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +void KisSelectionManager::grow (TQ_INT32 xradius, TQ_INT32 yradius) +{ + KisImageSP img = m_parent->currentImg(); + if (!img) return; + + KisPaintDeviceSP dev = img->activeDevice(); + if (!dev) return; + + if (!dev->hasSelection()) return; + KisSelectionSP selection = dev->selection(); + + //determine the layerSize + TQRect layerSize = dev->exactBounds(); + /* + Any bugs in this fuction are probably also in thin_region + Blame all bugs in this function on jaycox@gimp.org + */ + + TQ_UINT8 **buf; // caches the region's pixel data + TQ_UINT8 **max; // caches the largest values for each column + + if (xradius <= 0 || yradius <= 0) + return; + + KisSelectedTransaction *t = 0; + + if (img->undo()) { + t = new KisSelectedTransaction(i18n("Grow"), dev); + Q_CHECK_PTR(t); + } + + max = new TQ_UINT8* [layerSize.width() + 2 * xradius]; + buf = new TQ_UINT8* [yradius + 1]; + for (TQ_INT32 i = 0; i < yradius + 1; i++) + { + buf[i] = new TQ_UINT8[layerSize.width()]; + } + TQ_UINT8* buffer = new TQ_UINT8[ ( layerSize.width() + 2 * xradius ) * ( yradius + 1 ) ]; + for (TQ_INT32 i = 0; i < layerSize.width() + 2 * xradius; i++) + { + if (i < xradius) + max[i] = buffer; + else if (i < layerSize.width() + xradius) + max[i] = &buffer[(yradius + 1) * (i - xradius)]; + else + max[i] = &buffer[(yradius + 1) * (layerSize.width() + xradius - 1)]; + + for (TQ_INT32 j = 0; j < xradius + 1; j++) + max[i][j] = 0; + } + /* offset the max pointer by xradius so the range of the array + is [-xradius] to [region->w + xradius] */ + max += xradius; + + TQ_UINT8* out = new TQ_UINT8[ layerSize.width() ]; // holds the new scan line we are computing + + TQ_INT32* circ = new TQ_INT32[ 2 * xradius + 1 ]; // holds the y coords of the filter's tqmask + computeBorder (circ, xradius, yradius); + + /* offset the circ pointer by xradius so the range of the array + is [-xradius] to [xradius] */ + circ += xradius; + + memset (buf[0], 0, layerSize.width()); + for (TQ_INT32 i = 0; i < yradius && i < layerSize.height(); i++) // load top of image + { + selection->readBytes(buf[i + 1], layerSize.x(), layerSize.y() + i, layerSize.width(), 1); + } + + for (TQ_INT32 x = 0; x < layerSize.width() ; x++) // set up max for top of image + { + max[x][0] = 0; // buf[0][x] is always 0 + max[x][1] = buf[1][x]; // MAX (buf[1][x], max[x][0]) always = buf[1][x] + for (TQ_INT32 j = 2; j < yradius + 1; j++) + { + max[x][j] = MAX(buf[j][x], max[x][j-1]); + } + } + + for (TQ_INT32 y = 0; y < layerSize.height(); y++) + { + rotatePointers (buf, yradius + 1); + if (y < layerSize.height() - (yradius)) + selection->readBytes(buf[yradius], layerSize.x(), layerSize.y() + y + yradius, layerSize.width(), 1); + else + memset (buf[yradius], 0, layerSize.width()); + for (TQ_INT32 x = 0; x < layerSize.width(); x++) /* update max array */ + { + for (TQ_INT32 i = yradius; i > 0; i--) + { + max[x][i] = MAX (MAX (max[x][i - 1], buf[i - 1][x]), buf[i][x]); + } + max[x][0] = buf[0][x]; + } + TQ_INT32 last_max = max[0][circ[-1]]; + TQ_INT32 last_index = 1; + for (TQ_INT32 x = 0; x < layerSize.width(); x++) /* render scan line */ + { + last_index--; + if (last_index >= 0) + { + if (last_max == 255) + out[x] = 255; + else + { + last_max = 0; + for (TQ_INT32 i = xradius; i >= 0; i--) + if (last_max < max[x + i][circ[i]]) + { + last_max = max[x + i][circ[i]]; + last_index = i; + } + out[x] = last_max; + } + } + else + { + last_index = xradius; + last_max = max[x + xradius][circ[xradius]]; + for (TQ_INT32 i = xradius - 1; i >= -xradius; i--) + if (last_max < max[x + i][circ[i]]) + { + last_max = max[x + i][circ[i]]; + last_index = i; + } + out[x] = last_max; + } + } + selection->writeBytes(out, layerSize.x(), layerSize.y() + y, layerSize.width(), 1); + } + /* undo the offsets to the pointers so we can free the malloced memmory */ + circ -= xradius; + max -= xradius; + //XXXX: replace delete by delete[] where it is necessary to avoid memory leaks! + delete[] circ; + delete[] buffer; + delete[] max; + for (TQ_INT32 i = 0; i < yradius + 1; i++) + delete[] buf[i]; + delete[] buf; + delete[] out; + + dev->setDirty(); + dev->emitSelectionChanged(); + + if (t) { + img->undoAdapter()->addCommand(t); + } +} + +void KisSelectionManager::shrink (TQ_INT32 xradius, TQ_INT32 yradius, bool edge_lock) +{ + + KisImageSP img = m_parent->currentImg(); + if (!img) return; + + KisPaintDeviceSP dev = img->activeDevice(); + if (!dev) return; + + if (!dev->hasSelection()) return; + KisSelectionSP selection = dev->selection(); + + //determine the layerSize + TQRect layerSize = dev->exactBounds(); + /* + pretty much the same as fatten_region only different + blame all bugs in this function on jaycox@gimp.org + */ + /* If edge_lock is true we assume that pixels outside the region + we are passed are identical to the edge pixels. + If edge_lock is false, we assume that pixels outside the region are 0 + */ + TQ_UINT8 **buf; // caches the the region's pixels + TQ_UINT8 **max; // caches the smallest values for each column + TQ_INT32 last_max, last_index; + + if (xradius <= 0 || yradius <= 0) + return; + + max = new TQ_UINT8* [layerSize.width() + 2 * xradius]; + buf = new TQ_UINT8* [yradius + 1]; + for (TQ_INT32 i = 0; i < yradius + 1; i++) + { + buf[i] = new TQ_UINT8[layerSize.width()]; + } + + TQ_INT32 buffer_size = (layerSize.width() + 2 * xradius + 1) * (yradius + 1); + TQ_UINT8* buffer = new TQ_UINT8[buffer_size]; + + if (edge_lock) + memset(buffer, 255, buffer_size); + else + memset(buffer, 0, buffer_size); + + for (TQ_INT32 i = 0; i < layerSize.width() + 2 * xradius; i++) + { + if (i < xradius) + if (edge_lock) + max[i] = buffer; + else + max[i] = &buffer[(yradius + 1) * (layerSize.width() + xradius)]; + else if (i < layerSize.width() + xradius) + max[i] = &buffer[(yradius + 1) * (i - xradius)]; + else + if (edge_lock) + max[i] = &buffer[(yradius + 1) * (layerSize.width() + xradius - 1)]; + else + max[i] = &buffer[(yradius + 1) * (layerSize.width() + xradius)]; + } + if (!edge_lock) + for (TQ_INT32 j = 0 ; j < xradius + 1; j++) max[0][j] = 0; + + // offset the max pointer by xradius so the range of the array is [-xradius] to [region->w + xradius] + max += xradius; + + TQ_UINT8* out = new TQ_UINT8[layerSize.width()]; // holds the new scan line we are computing + + TQ_INT32* circ = new TQ_INT32[2 * xradius + 1]; // holds the y coords of the filter's tqmask + + computeBorder (circ, xradius, yradius); + + // offset the circ pointer by xradius so the range of the array is [-xradius] to [xradius] + circ += xradius; + + for (TQ_INT32 i = 0; i < yradius && i < layerSize.height(); i++) // load top of image + selection->readBytes(buf[i + 1], layerSize.x(), layerSize.y() + i, layerSize.width(), 1); + + if (edge_lock) + memcpy (buf[0], buf[1], layerSize.width()); + else + memset (buf[0], 0, layerSize.width()); + + + for (TQ_INT32 x = 0; x < layerSize.width(); x++) // set up max for top of image + { + max[x][0] = buf[0][x]; + for (TQ_INT32 j = 1; j < yradius + 1; j++) + max[x][j] = MIN(buf[j][x], max[x][j-1]); + } + + for (TQ_INT32 y = 0; y < layerSize.height(); y++) + { + rotatePointers (buf, yradius + 1); + if (y < layerSize.height() - yradius) + selection->readBytes(buf[yradius], layerSize.x(), layerSize.y() + y + yradius, layerSize.width(), 1); + else if (edge_lock) + memcpy (buf[yradius], buf[yradius - 1], layerSize.width()); + else + memset (buf[yradius], 0, layerSize.width()); + + for (TQ_INT32 x = 0 ; x < layerSize.width(); x++) // update max array + { + for (TQ_INT32 i = yradius; i > 0; i--) + { + max[x][i] = MIN (MIN (max[x][i - 1], buf[i - 1][x]), buf[i][x]); + } + max[x][0] = buf[0][x]; + } + last_max = max[0][circ[-1]]; + last_index = 0; + + for (TQ_INT32 x = 0 ; x < layerSize.width(); x++) // render scan line + { + last_index--; + if (last_index >= 0) + { + if (last_max == 0) + out[x] = 0; + else + { + last_max = 255; + for (TQ_INT32 i = xradius; i >= 0; i--) + if (last_max > max[x + i][circ[i]]) + { + last_max = max[x + i][circ[i]]; + last_index = i; + } + out[x] = last_max; + } + } + else + { + last_index = xradius; + last_max = max[x + xradius][circ[xradius]]; + for (TQ_INT32 i = xradius - 1; i >= -xradius; i--) + if (last_max > max[x + i][circ[i]]) + { + last_max = max[x + i][circ[i]]; + last_index = i; + } + out[x] = last_max; + } + } + selection->writeBytes(out, layerSize.x(), layerSize.y() + y, layerSize.width(), 1); + } + + // undo the offsets to the pointers so we can free the malloced memmory + circ -= xradius; + max -= xradius; + //free the memmory + //XXXX: replace delete by delete[] where it is necessary to avoid memory leaks! + delete[] circ; + delete[] buffer; + delete[] max; + for (TQ_INT32 i = 0; i < yradius + 1; i++) + delete buf[i]; + delete[] buf; + delete[] out; + + dev->setDirty(layerSize); + dev->emitSelectionChanged(); +} + +//Simple convolution filter to smooth a tqmask (1bpp) + +void KisSelectionManager::smooth() +{ + KisImageSP img = m_parent->currentImg(); + if (!img) return; + + KisPaintDeviceSP dev = img->activeDevice(); + if (!dev) return; + + if (!dev->hasSelection()) return; + KisSelectionSP selection = dev->selection(); + + //determine the layerSize + TQRect layerSize = dev->exactBounds(); + + TQ_UINT8 *buf[3]; + + TQ_INT32 width = layerSize.width(); + + for (TQ_INT32 i = 0; i < 3; i++) buf[i] = new TQ_UINT8[width + 2]; + + TQ_UINT8* out = new TQ_UINT8[width]; + + // load top of image + selection->readBytes(buf[0] + 1, layerSize.x(), layerSize.y(), width, 1); + + buf[0][0] = buf[0][1]; + buf[0][width + 1] = buf[0][width]; + + memcpy (buf[1], buf[0], width + 2); + + for (TQ_INT32 y = 0; y < layerSize.height(); y++) + { + if (y + 1 < layerSize.height()) + { + selection->readBytes(buf[2] + 1, layerSize.x(), layerSize.y() + y + 1, width, 1); + + buf[2][0] = buf[2][1]; + buf[2][width + 1] = buf[2][width]; + } + else + { + memcpy (buf[2], buf[1], width + 2); + } + + for (TQ_INT32 x = 0 ; x < width; x++) + { + TQ_INT32 value = (buf[0][x] + buf[0][x+1] + buf[0][x+2] + + buf[1][x] + buf[2][x+1] + buf[1][x+2] + + buf[2][x] + buf[1][x+1] + buf[2][x+2]); + + out[x] = value / 9; + } + + selection->writeBytes(out, layerSize.x(), layerSize.y() + y, width, 1); + + rotatePointers (buf, 3); + } + + for (TQ_INT32 i = 0; i < 3; i++) + delete[] buf[i]; + + delete[] out; + + dev->setDirty(); + dev->emitSelectionChanged(); +} + +// Erode (radius 1 pixel) a tqmask (1bpp) + +void KisSelectionManager::erode() +{ + KisImageSP img = m_parent->currentImg(); + if (!img) return; + + KisPaintDeviceSP dev = img->activeDevice(); + if (!dev) return; + + if (!dev->hasSelection()) return; + KisSelectionSP selection = dev->selection(); + + //determine the layerSize + TQRect layerSize = dev->exactBounds(); + + TQ_UINT8* buf[3]; + + + TQ_INT32 width = layerSize.width(); + + for (TQ_INT32 i = 0; i < 3; i++) + buf[i] = new TQ_UINT8[width + 2]; + + TQ_UINT8* out = new TQ_UINT8[width]; + + // load top of image + selection->readBytes(buf[0] + 1, layerSize.x(), layerSize.y(), width, 1); + + buf[0][0] = buf[0][1]; + buf[0][width + 1] = buf[0][width]; + + memcpy (buf[1], buf[0], width + 2); + + for (TQ_INT32 y = 0; y < layerSize.height(); y++) + { + if (y + 1 < layerSize.height()) + { + selection->readBytes(buf[2] + 1, layerSize.x(), layerSize.y() + y + 1, width, 1); + + buf[2][0] = buf[2][1]; + buf[2][width + 1] = buf[2][width]; + } + else + { + memcpy (buf[2], buf[1], width + 2); + } + + for (TQ_INT32 x = 0 ; x < width; x++) + { + TQ_INT32 min = 255; + + if (buf[0][x+1] < min) min = buf[0][x+1]; + if (buf[1][x] < min) min = buf[1][x]; + if (buf[1][x+1] < min) min = buf[1][x+1]; + if (buf[1][x+2] < min) min = buf[1][x+2]; + if (buf[2][x+1] < min) min = buf[2][x+1]; + + out[x] = min; + } + + selection->writeBytes(out, layerSize.x(), layerSize.y() + y, width, 1); + + rotatePointers (buf, 3); + } + + for (TQ_INT32 i = 0; i < 3; i++) + delete[] buf[i]; + + delete[] out; + + dev->setDirty(); + dev->emitSelectionChanged(); +} + +// dilate (radius 1 pixel) a tqmask (1bpp) + +void KisSelectionManager::dilate() +{ + KisImageSP img = m_parent->currentImg(); + if (!img) return; + + KisPaintDeviceSP dev = img->activeDevice(); + if (!dev) return; + + if (!dev->hasSelection()) return; + KisSelectionSP selection = dev->selection(); + + //determine the layerSize + TQRect layerSize = dev->exactBounds(); + + TQ_UINT8* buf[3]; + + TQ_INT32 width = layerSize.width(); + + for (TQ_INT32 i = 0; i < 3; i++) + buf[i] = new TQ_UINT8[width + 2]; + + TQ_UINT8* out = new TQ_UINT8[width]; + + // load top of image + selection->readBytes(buf[0] + 1, layerSize.x(), layerSize.y(), width, 1); + + buf[0][0] = buf[0][1]; + buf[0][width + 1] = buf[0][width]; + + memcpy (buf[1], buf[0], width + 2); + + for (TQ_INT32 y = 0; y < layerSize.height(); y++) + { + if (y + 1 < layerSize.height()) + { + selection->readBytes(buf[2] + 1, layerSize.x(), layerSize.y() + y + 1, width, 1); + + buf[2][0] = buf[2][1]; + buf[2][width + 1] = buf[2][width]; + } + else + { + memcpy (buf[2], buf[1], width + 2); + } + + for (TQ_INT32 x = 0 ; x < width; x++) + { + TQ_INT32 max = 0; + + if (buf[0][x+1] > max) max = buf[0][x+1]; + if (buf[1][x] > max) max = buf[1][x]; + if (buf[1][x+1] > max) max = buf[1][x+1]; + if (buf[1][x+2] > max) max = buf[1][x+2]; + if (buf[2][x+1] > max) max = buf[2][x+1]; + + out[x] = max; + } + + selection->writeBytes(out, layerSize.x(), layerSize.y() + y, width, 1); + + rotatePointers (buf, 3); + } + + for (TQ_INT32 i = 0; i < 3; i++) + delete[] buf[i]; + + delete[] out; + + dev->setDirty(); + dev->emitSelectionChanged(); +} + +void KisSelectionManager::border(TQ_INT32 xradius, TQ_INT32 yradius) +{ + KisImageSP img = m_parent->currentImg(); + if (!img) return; + + KisPaintDeviceSP dev = img->activeDevice(); + if (!dev) return; + + if (!dev->hasSelection()) return; + KisSelectionSP selection = dev->selection(); + + //determine the layerSize + TQRect layerSize = dev->exactBounds(); + + /* + This function has no bugs, but if you imagine some you can + blame them on jaycox@gimp.org + */ + TQ_UINT8 *buf[3]; + TQ_UINT8 **density; + TQ_UINT8 **transition; + + if (xradius == 1 && yradius == 1) // optimize this case specifically + { + TQ_UINT8* source[3]; + + for (TQ_INT32 i = 0; i < 3; i++) + source[i] = new TQ_UINT8[layerSize.width()]; + + TQ_UINT8* transition = new TQ_UINT8[layerSize.width()]; + + selection->readBytes(source[0], layerSize.x(), layerSize.y(), layerSize.width(), 1); + memcpy (source[1], source[0], layerSize.width()); + if (layerSize.height() > 1) + selection->readBytes(source[2], layerSize.x(), layerSize.y() + 1, layerSize.width(), 1); + else + memcpy (source[2], source[1], layerSize.width()); + + computeTransition (transition, source, layerSize.width()); + selection->writeBytes(transition, layerSize.x(), layerSize.y(), layerSize.width(), 1); + + for (TQ_INT32 y = 1; y < layerSize.height(); y++) + { + rotatePointers (source, 3); + if (y + 1 < layerSize.height()) + selection->readBytes(source[2], layerSize.x(), layerSize.y() + y + 1, layerSize.width(), 1); + else + memcpy(source[2], source[1], layerSize.width()); + computeTransition (transition, source, layerSize.width()); + selection->writeBytes(transition, layerSize.x(), layerSize.y() + y, layerSize.width(), 1); + } + + for (TQ_INT32 i = 0; i < 3; i++) + delete[] source[i]; + delete[] transition; + return; + } + + TQ_INT32* max = new TQ_INT32[layerSize.width() + 2 * xradius]; + for (TQ_INT32 i = 0; i < (layerSize.width() + 2 * xradius); i++) + max[i] = yradius + 2; + max += xradius; + + for (TQ_INT32 i = 0; i < 3; i++) + buf[i] = new TQ_UINT8[layerSize.width()]; + + transition = new TQ_UINT8*[yradius + 1]; + for (TQ_INT32 i = 0; i < yradius + 1; i++) + { + transition[i] = new TQ_UINT8[layerSize.width() + 2 * xradius]; + memset(transition[i], 0, layerSize.width() + 2 * xradius); + transition[i] += xradius; + } + TQ_UINT8* out = new TQ_UINT8[layerSize.width()]; + density = new TQ_UINT8*[2 * xradius + 1]; + density += xradius; + + for (TQ_INT32 x = 0; x < (xradius + 1); x++) // allocate density[][] + { + density[ x] = new TQ_UINT8[2 * yradius + 1]; + density[ x] += yradius; + density[-x] = density[x]; + } + for (TQ_INT32 x = 0; x < (xradius + 1); x++) // compute density[][] + { + double tmpx, tmpy, dist; + TQ_UINT8 a; + + if (x > 0) + tmpx = x - 0.5; + else if (x < 0) + tmpx = x + 0.5; + else + tmpx = 0.0; + + for (TQ_INT32 y = 0; y < (yradius + 1); y++) + { + if (y > 0) + tmpy = y - 0.5; + else if (y < 0) + tmpy = y + 0.5; + else + tmpy = 0.0; + dist = ((tmpy * tmpy) / (yradius * yradius) + + (tmpx * tmpx) / (xradius * xradius)); + if (dist < 1.0) + a = 255 * (TQ_UINT8)(1.0 - sqrt (dist)); + else + a = 0; + density[ x][ y] = a; + density[ x][-y] = a; + density[-x][ y] = a; + density[-x][-y] = a; + } + } + selection->readBytes(buf[0], layerSize.x(), layerSize.y(), layerSize.width(), 1); + memcpy (buf[1], buf[0], layerSize.width()); + if (layerSize.height() > 1) + selection->readBytes(buf[2], layerSize.x(), layerSize.y() + 1, layerSize.width(), 1); + else + memcpy (buf[2], buf[1], layerSize.width()); + computeTransition (transition[1], buf, layerSize.width()); + + for (TQ_INT32 y = 1; y < yradius && y + 1 < layerSize.height(); y++) // set up top of image + { + rotatePointers (buf, 3); + selection->readBytes(buf[2], layerSize.x(), layerSize.y() + y + 1, layerSize.width(), 1); + computeTransition (transition[y + 1], buf, layerSize.width()); + } + for (TQ_INT32 x = 0; x < layerSize.width(); x++) // set up max[] for top of image + { + max[x] = -(yradius + 7); + for (TQ_INT32 j = 1; j < yradius + 1; j++) + if (transition[j][x]) + { + max[x] = j; + break; + } + } + for (TQ_INT32 y = 0; y < layerSize.height(); y++) // main calculation loop + { + rotatePointers (buf, 3); + rotatePointers (transition, yradius + 1); + if (y < layerSize.height() - (yradius + 1)) + { + selection->readBytes(buf[2], layerSize.x(), layerSize.y() + y + yradius + 1, layerSize.width(), 1); + computeTransition (transition[yradius], buf, layerSize.width()); + } + else + memcpy (transition[yradius], transition[yradius - 1], layerSize.width()); + + for (TQ_INT32 x = 0; x < layerSize.width(); x++) // update max array + { + if (max[x] < 1) + { + if (max[x] <= -yradius) + { + if (transition[yradius][x]) + max[x] = yradius; + else + max[x]--; + } + else + if (transition[-max[x]][x]) + max[x] = -max[x]; + else if (transition[-max[x] + 1][x]) + max[x] = -max[x] + 1; + else + max[x]--; + } + else + max[x]--; + if (max[x] < -yradius - 1) + max[x] = -yradius - 1; + } + TQ_UINT8 last_max = max[0][density[-1]]; + TQ_INT32 last_index = 1; + for (TQ_INT32 x = 0 ; x < layerSize.width(); x++) // render scan line + { + last_index--; + if (last_index >= 0) + { + last_max = 0; + for (TQ_INT32 i = xradius; i >= 0; i--) + if (max[x + i] <= yradius && max[x + i] >= -yradius && density[i][max[x+i]] > last_max) + { + last_max = density[i][max[x + i]]; + last_index = i; + } + out[x] = last_max; + } + else + { + last_max = 0; + for (TQ_INT32 i = xradius; i >= -xradius; i--) + if (max[x + i] <= yradius && max[x + i] >= -yradius && density[i][max[x + i]] > last_max) + { + last_max = density[i][max[x + i]]; + last_index = i; + } + out[x] = last_max; + } + if (last_max == 0) + { + TQ_INT32 i; + for (i = x + 1; i < layerSize.width(); i++) + { + if (max[i] >= -yradius) + break; + } + if (i - x > xradius) + { + for (; x < i - xradius; x++) + out[x] = 0; + x--; + } + last_index = xradius; + } + } + selection->writeBytes(out, layerSize.x(), layerSize.y() + y, layerSize.width(), 1); + } + delete [] out; + + for (TQ_INT32 i = 0; i < 3; i++) + delete buf[i]; + + max -= xradius; + delete[] max; + + for (TQ_INT32 i = 0; i < yradius + 1; i++) + { + transition[i] -= xradius; + delete transition[i]; + } + delete[] transition; + + for (TQ_INT32 i = 0; i < xradius + 1 ; i++) + { + density[i] -= yradius; + delete density[i]; + } + density -= xradius; + delete[] density; + + dev->setDirty(); + dev->emitSelectionChanged(); +} + +#define RINT(x) floor ((x) + 0.5) + +void KisSelectionManager::computeBorder (TQ_INT32 *circ, TQ_INT32 xradius, TQ_INT32 yradius) +{ + Q_ASSERT(xradius != 0); + TQ_INT32 i; + TQ_INT32 diameter = xradius * 2 + 1; + double tmp; + + for (i = 0; i < diameter; i++) + { + if (i > xradius) + tmp = (i - xradius) - 0.5; + else if (i < xradius) + tmp = (xradius - i) - 0.5; + else + tmp = 0.0; + + circ[i] = (TQ_INT32) RINT (yradius / (double) xradius * sqrt (xradius * xradius - tmp * tmp)); + } +} + +void KisSelectionManager::rotatePointers (TQ_UINT8 **p, TQ_UINT32 n) +{ + TQ_UINT32 i; + TQ_UINT8 *tmp; + + tmp = p[0]; + + for (i = 0; i < n - 1; i++) p[i] = p[i + 1]; + + p[i] = tmp; +} + +void KisSelectionManager::computeTransition (TQ_UINT8* transition, TQ_UINT8** buf, TQ_INT32 width) +{ + TQ_INT32 x = 0; + + if (width == 1) + { + if (buf[1][x] > 127 && (buf[0][x] < 128 || buf[2][x] < 128)) + transition[x] = 255; + else + transition[x] = 0; + return; + } + if (buf[1][x] > 127) + { + if ( buf[0][x] < 128 || buf[0][x + 1] < 128 || + buf[1][x + 1] < 128 || + buf[2][x] < 128 || buf[2][x + 1] < 128 ) + transition[x] = 255; + else + transition[x] = 0; + } + else + transition[x] = 0; + for (TQ_INT32 x = 1; x < width - 1; x++) + { + if (buf[1][x] >= 128) + { + if (buf[0][x - 1] < 128 || buf[0][x] < 128 || buf[0][x + 1] < 128 || + buf[1][x - 1] < 128 || buf[1][x + 1] < 128 || + buf[2][x - 1] < 128 || buf[2][x] < 128 || buf[2][x + 1] < 128) + transition[x] = 255; + else + transition[x] = 0; + } + else + transition[x] = 0; + } + if (buf[1][x] >= 128) + { + if (buf[0][x - 1] < 128 || buf[0][x] < 128 || + buf[1][x - 1] < 128 || + buf[2][x - 1] < 128 || buf[2][x] < 128) + transition[x] = 255; + else + transition[x] = 0; + } + else + transition[x] = 0; +} + +#include "kis_selection_manager.moc" diff --git a/chalk/ui/kis_selection_manager.h b/chalk/ui/kis_selection_manager.h new file mode 100644 index 00000000..fb33218e --- /dev/null +++ b/chalk/ui/kis_selection_manager.h @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_SELECTION_MANAGER_ +#define KIS_SELECTION_MANAGER_ + +#include "tqobject.h" +#include "tqptrlist.h" + +#include "kis_image.h" +#include <koffice_export.h> + +class KAction; +class KisView; +class KisDoc; +class KisClipboard; + +/** + * The selection manager is responsible selections + * and the clipboard. + */ +class KRITACORE_EXPORT KisSelectionManager : public TQObject { + + Q_OBJECT + TQ_OBJECT + +public: + + KisSelectionManager(KisView * tqparent, KisDoc * doc); + virtual ~KisSelectionManager(); + + void setup(KActionCollection * collection); + + void addSelectionAction(KAction * action); + +public: + /** + * This function return if the selection should be displayed + */ + bool displaySelection(); + +public slots: + + void updateGUI(); + void imgSelectionChanged(KisImageSP img); + void clipboardDataChanged(); + + void cut(); + void copy(); + KisLayerSP paste(); + void pasteNew(); + void cutToNewLayer(); + void selectAll(); + void deselect(); + void clear(); + void fillForegroundColor(); + void fillBackgroundColor(); + void fillPattern(); + void reselect(); + void invert(); + void copySelectionToNewLayer(); + void feather(); + void border(); + void expand(); + void contract(); + void smooth(); + void similar(); + void transform(); + void load(); + void save(); + void toggleDisplaySelection(); + +public: + void grow (TQ_INT32 xradius, TQ_INT32 yradius); + void shrink (TQ_INT32 xradius, TQ_INT32 yradius, bool edge_lock); + void border(TQ_INT32 xradius, TQ_INT32 yradius); + // the following functions are needed for the siox tool + // they might be also usefull on its own + void erode(); + void dilate(); + +private: + void fill(const KisColor& color, bool fillWithPattern, const TQString& transactionText); + + void computeBorder (TQ_INT32 *circ, TQ_INT32 xradius, TQ_INT32 yradius); + inline void rotatePointers (TQ_UINT8 **p, TQ_UINT32 n); + void computeTransition (TQ_UINT8* transition, TQ_UINT8** buf, TQ_INT32 width); + + KisView * m_parent; + KisDoc * m_doc; + + KisClipboard * m_clipboard; + + KAction *m_copy; + KAction *m_cut; + KAction *m_paste; + KAction *m_pasteNew; + KAction *m_cutToNewLayer; + KAction *m_selectAll; + KAction *m_deselect; + KAction *m_clear; + KAction *m_reselect; + KAction *m_invert; + KAction *m_toNewLayer; + KAction *m_feather; + KAction *m_border; + KAction *m_expand; + KAction *m_smooth; + KAction *m_contract; + KAction *m_similar; + KAction *m_transform; + KAction *m_load; + KAction *m_save; + KAction *m_fillForegroundColor; + KAction *m_fillBackgroundColor; + KAction *m_fillPattern; + KToggleAction *m_toggleDisplaySelection; + + TQPtrList<KAction> m_pluginActions; + +}; + +#endif // KIS_SELECTION_MANAGER_ diff --git a/chalk/ui/kis_selection_options.cc b/chalk/ui/kis_selection_options.cc new file mode 100644 index 00000000..f94ff17f --- /dev/null +++ b/chalk/ui/kis_selection_options.cc @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <tqwidget.h> +#include <tqradiobutton.h> +#include <tqcombobox.h> +#include <kcolorbtn.h> +#include <tqlayout.h> + +#include "kis_canvas_controller.h" +#include "kis_canvas_subject.h" +#include "wdgselectionoptions.h" +#include "kis_selection_options.h" +#include "kis_types.h" +#include "kis_layer.h" +#include "kis_image.h" +#include "kis_selection.h" +#include "kis_paint_device.h" + +KisSelectionOptions::KisSelectionOptions(TQWidget *tqparent, KisCanvasSubject * subject) + : super(tqparent), + m_subject(subject) +{ + m_page = new WdgSelectionOptions(this); + Q_CHECK_PTR(m_page); + + TQVBoxLayout * l = new TQVBoxLayout(this); + l->addWidget(m_page); + + connect(m_page->cmbAction, TQT_SIGNAL(activated(int)), this, TQT_SIGNAL(actionChanged(int))); +} + +KisSelectionOptions::~KisSelectionOptions() +{ +} + +int KisSelectionOptions::action() +{ + return m_page->cmbAction->currentItem(); +} + +void KisSelectionOptions::slotActivated() +{ + + if (!m_subject) return; + KisImageSP img = m_subject->currentImg(); + if (!img) return; + KisPaintDeviceSP dev = img->activeDevice(); + if (!dev) return; + + if (dev->hasSelection()) { + } +} + +#include "kis_selection_options.moc" diff --git a/chalk/ui/kis_selection_options.h b/chalk/ui/kis_selection_options.h new file mode 100644 index 00000000..e8168d04 --- /dev/null +++ b/chalk/ui/kis_selection_options.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __KIS_SELECTION_OPTIONS_H__ +#define __KIS_SELECTION_OPTIONS_H__ + +#include <tqwidget.h> + +#include "koffice_export.h" + +class KisCanvasSubject; +class WdgSelectionOptions; + +/** + */ +class KRITAUI_EXPORT KisSelectionOptions : public TQWidget +{ + + Q_OBJECT + TQ_OBJECT + + typedef TQWidget super; + +public: + KisSelectionOptions( TQWidget *tqparent, KisCanvasSubject * subject); + virtual ~KisSelectionOptions(); + + int action(); + +signals: + void actionChanged(int); + +public slots: + void slotActivated(); + +private: + WdgSelectionOptions * m_page; + KisCanvasSubject* m_subject; +}; + +#endif + diff --git a/chalk/ui/kis_text_brush.cc b/chalk/ui/kis_text_brush.cc new file mode 100644 index 00000000..ef376373 --- /dev/null +++ b/chalk/ui/kis_text_brush.cc @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2004 Cyrille Berger <cberger@cberger.net> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <tqfontmetrics.h> +#include <tqpainter.h> +#include <tqspinbox.h> +#include <tqcheckbox.h> +#include <tqlabel.h> + +#include <kfontdialog.h> + +#include <klineedit.h> +#include "kis_text_brush.h" + +void KisTextBrushResource::updateBrush() +{ + TQFontMetrics metric(m_font); + int w = metric.width(m_txt); + int h = metric.height(); + TQPixmap px(w,h); + TQPainter p; + p.begin(&px); + p.setFont( m_font ); + p.fillRect(0,0, w, h, TQt::white); + p.setPen(TQt::black); + p.drawText(0, metric.ascent(), m_txt ); + p.end(); + setImage(px.convertToImage ()); +} + +KisTextBrush::KisTextBrush(TQWidget *tqparent, const char* name, const TQString& caption) + : KisWdgTextBrush(tqparent, name), + m_textBrushResource(new KisTextBrushResource()) +{ + setCaption(caption); + connect((TQObject*)lineEdit, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(rebuildTextBrush())); + connect((TQObject*)bnFont, TQT_SIGNAL(clicked()), this, TQT_SLOT(getFont())); + m_font = font(); + rebuildTextBrush(); +} + + +void KisTextBrush::getFont() +{ + KFontDialog::getFont( m_font, false/*, TQWidget* tqparent! */ ); + rebuildTextBrush(); +} + +void KisTextBrush::rebuildTextBrush() +{ + lblFont->setText(TQString(m_font.family() + ", %1").tqarg(m_font.pointSize())); + lblFont->setFont(m_font); + m_textBrushResource->setFont(m_font); + m_textBrushResource->setText(lineEdit->text()); + m_textBrushResource->updateBrush(); + emit(activatedResource(m_textBrushResource)); +} + +#include "kis_text_brush.moc" diff --git a/chalk/ui/kis_text_brush.h b/chalk/ui/kis_text_brush.h new file mode 100644 index 00000000..3c8835de --- /dev/null +++ b/chalk/ui/kis_text_brush.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2004 Cyrille Berger <cberger@cberger.net> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _KIS_TEXT_BRUSH_H_ +#define _KIS_TEXT_BRUSH_H_ + +#include "wdgtextbrush.h" +#include "kis_brush.h" + +class KisTextBrushResource : public KisBrush +{ + public: + KisTextBrushResource() : KisBrush("") + { + setBrushType(MASK); + } + KisTextBrushResource(const TQString& txt, const TQFont& font) : KisBrush("") + { + setFont(font); + setText(txt); + updateBrush(); + setBrushType(MASK); + }; + public: + virtual bool load() { return false; }; + void setText(const TQString& txt) { m_txt = txt; }; + void setFont(const TQFont& font) { m_font = font; }; + void updateBrush(); + private: + TQFont m_font; + TQString m_txt; +}; + +class KisTextBrush : public KisWdgTextBrush +{ + Q_OBJECT + TQ_OBJECT +public: + KisTextBrush(TQWidget *tqparent, const char* name, const TQString& caption); + +signals: + void activatedResource(KisResource *r); + +private slots: + void rebuildTextBrush(); + void getFont(); + +private: + KisTextBrushResource* m_textBrushResource; + TQFont m_font; +}; + + + + +#endif diff --git a/chalk/ui/kis_tool.cc b/chalk/ui/kis_tool.cc new file mode 100644 index 00000000..5aee554b --- /dev/null +++ b/chalk/ui/kis_tool.cc @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2002, 2003 Patrick Julien <freak@codepimps.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <tqwidget.h> +#include <tqstring.h> +#include <kaction.h> +#include <tqlabel.h> + +#include <klocale.h> +#include <kdebug.h> + +#include "kis_tool.h" +#include "kis_tool.moc" + + +class KisTool::KisToolPrivate +{ +public: + TQString uiname; + TQLabel * optionWidget; +}; + +KisTool::KisTool(const TQString & name) +{ + m_action = 0; + m_ownAction = false; + d = new KisToolPrivate(); + d->uiname = name; + d->optionWidget = 0; +} + +KisTool::~KisTool() +{ + if (m_ownAction) { + delete m_action; + m_action = 0; + } + delete d; +} + +TQWidget* KisTool::createOptionWidget(TQWidget* tqparent) +{ + + d->optionWidget = new TQLabel(i18n("No options for %1.").tqarg(d->uiname), tqparent); + d->optionWidget->setCaption(d->uiname); + d->optionWidget->tqsetAlignment(TQt::AlignCenter); + return d->optionWidget; +} + +TQWidget* KisTool::optionWidget() +{ + return d->optionWidget; +} + diff --git a/chalk/ui/kis_tool.h b/chalk/ui/kis_tool.h new file mode 100644 index 00000000..c8f2d349 --- /dev/null +++ b/chalk/ui/kis_tool.h @@ -0,0 +1,144 @@ +/* + * Copyright (c) 1999 Matthias Elter <me@kde.org> + * Copyright (c) 2002, 2003 Patrick Julien <freak@codepimps.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_TOOL_H_ +#define KIS_TOOL_H_ + +#include <tqobject.h> +#include <tqstring.h> + +#include <ksharedptr.h> +#include <kaction.h> + +#include "kis_shared_ptr_vector.h" +#include "kis_canvas_observer.h" + +class TQCursor; +class TQEvent; +class TQKeyEvent; +class TQRect; +class TQWidget; +class KActionCollection; +class KRadioAction; +class KDialog; +class KisBrush; +class KisGradient; +class KisPattern; +class KisButtonPressEvent; +class KisButtonReleaseEvent; +class KisDoubleClickEvent; +class KisMoveEvent; +class KisCanvasPainter; + +enum enumToolType { + TOOL_SHAPE = 0, // Geometric tqshapes like ellipses and lines + TOOL_FREEHAND = 1, // Freehand drawing tools + TOOL_TRANSFORM = 2, // Tools that transform the layer + TOOL_FILL = 3, // Tools that fill parts of the canvas + TOOL_VIEW = 4, // Tools that affect the canvas: pan, zoom, etc. + TOOL_SELECT = 5 + +}; + +const TQ_UINT8 NUMBER_OF_TOOLTYPES = 6; + +class KisTool : public TQObject, public KisCanvasObserver, public KShared { + Q_OBJECT + TQ_OBJECT + +public: + KisTool(const TQString & name); + virtual ~KisTool(); + +public: + + virtual void paint(KisCanvasPainter& gc) = 0; + virtual void paint(KisCanvasPainter& gc, const TQRect& rc) = 0; + + /** + * This function is called after the creation of a tool to create the KAction corresponding + * to the tool. + * + * The code should look like : + * @code + * + * @endcode + */ + virtual void setup(KActionCollection *collection) = 0; + + virtual void buttonPress(KisButtonPressEvent *e) = 0; + virtual void move(KisMoveEvent *e) = 0; + virtual void buttonRelease(KisButtonReleaseEvent *e) = 0; + virtual void doubleClick(KisDoubleClickEvent *e) = 0; + virtual void keyPress(TQKeyEvent *e) = 0; + virtual void keyRelease(TQKeyEvent *e) = 0; + + virtual TQCursor cursor() = 0; + virtual void setCursor(const TQCursor& cursor) = 0; + /** + * This function is called to create the configuration widget of the tool. + * @param tqparent the tqparent of the widget + */ + virtual TQWidget* createOptionWidget(TQWidget* tqparent); + /** + * @return the current configuration widget. + */ + virtual TQWidget* optionWidget(); + KRadioAction *action() const { return m_action; } + + /** + * Return true if this tool wants auto canvas-scrolling to + * work when this tool is active. + */ + virtual bool wantsAutoScroll() const { return true; } + + // Methods for integration with karbon-style toolbox + virtual TQ_UINT32 priority() { return 0; } + virtual enumToolType toolType() { return TOOL_FREEHAND; } + virtual TQString icon() { return m_action->icon(); } + virtual TQString quickHelp() const { return ""; } + +public slots: + /** + * This slot is called when the tool is selected in the toolbox + */ + virtual void activate() = 0; + + /** + * deactivate is called when the tool gets deactivated because another + * tool is selected. Tools can then clean up after themselves. + */ + virtual void deactivate() = 0; + +private: + KisTool(const KisTool&); + KisTool& operator=(const KisTool&); + +protected: + KRadioAction *m_action; + bool m_ownAction; + +private: + class KisToolPrivate; + KisToolPrivate * d; + +}; + +#endif // KIS_TOOL_H_ + diff --git a/chalk/ui/kis_tool_controller.h b/chalk/ui/kis_tool_controller.h new file mode 100644 index 00000000..f135b86e --- /dev/null +++ b/chalk/ui/kis_tool_controller.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2003 Patrick Julien <freak@codepimps.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_TOOL_CONTROLLER_H_ +#define KIS_TOOL_CONTROLLER_H_ + +class KisTool; + +class KisToolControllerInterface { +public: + KisToolControllerInterface() {}; + virtual ~KisToolControllerInterface() {}; + +public: + virtual void setCurrentTool(KisTool *tool) = 0; + virtual KisTool *currentTool() const = 0; + +private: + KisToolControllerInterface(const KisToolControllerInterface&); + KisToolControllerInterface& operator=(const KisToolControllerInterface&); +}; + +#endif // KIS_TOOL_CONTROLLER_H_ + diff --git a/chalk/ui/kis_tool_dummy.cc b/chalk/ui/kis_tool_dummy.cc new file mode 100644 index 00000000..d8ac04e5 --- /dev/null +++ b/chalk/ui/kis_tool_dummy.cc @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2004 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <tqwidget.h> +#include <tqstring.h> +#include <kaction.h> +#include <tqlabel.h> + +#include <kaction.h> +#include <klocale.h> + +#include "kis_canvas_controller.h" +#include "kis_canvas_subject.h" +#include "kis_cursor.h" +#include "kis_tool_dummy.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" + +KisToolDummy::KisToolDummy() + : super(i18n("No Active Tool")) +{ + setName("tool_dummy"); + m_subject = 0; + m_dragging = false; + m_optionWidget = 0; + setCursor(TQCursor::forbiddenCursor); +} + +KisToolDummy::~KisToolDummy() +{ +} + +void KisToolDummy::update(KisCanvasSubject *subject) +{ + m_subject = subject; + super::update(m_subject); +} + +void KisToolDummy::buttonPress(KisButtonPressEvent *e) +{ + if (m_subject && !m_dragging && e->button() == Qt::LeftButton) { + KisCanvasController *controller = m_subject->canvasController(); + + m_origScrollX = controller->horzValue(); + m_origScrollY = controller->vertValue(); + m_dragPos = controller->windowToView(e->pos()); + m_dragging = true; + } +} + +void KisToolDummy::move(KisMoveEvent *e) +{ + if (m_subject && m_dragging) { + KisCanvasController *controller = m_subject->canvasController(); + + KisPoint currPos = controller->windowToView(e->pos()); + KisPoint delta = currPos - m_dragPos; + controller->scrollTo(m_origScrollX - delta.floorX(), m_origScrollY - delta.floorY()); + } +} + +void KisToolDummy::buttonRelease(KisButtonReleaseEvent *e) +{ + if (m_subject && m_dragging && e->button() == Qt::LeftButton) { + m_dragging = false; + } +} + +void KisToolDummy::setup(KActionCollection *collection) +{ + m_action = static_cast<KRadioAction *>(collection->action(name())); + + if (m_action == 0) { + m_action = new KRadioAction(i18n("&Dummy"), "tool_dummy", TQt::SHIFT+TQt::Key_H, this, TQT_SLOT(activate()), collection, name()); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + + +TQWidget* KisToolDummy::createOptionWidget(TQWidget* tqparent) +{ + m_optionWidget = new TQLabel(i18n("Layer is locked or invisible."), tqparent); + m_optionWidget->setCaption(i18n("No Active Tool")); + m_optionWidget->tqsetAlignment(TQt::AlignCenter); + return m_optionWidget; +} + +TQWidget* KisToolDummy::optionWidget() +{ + return m_optionWidget; +} + + +#include "kis_tool_dummy.moc" diff --git a/chalk/ui/kis_tool_dummy.h b/chalk/ui/kis_tool_dummy.h new file mode 100644 index 00000000..d10850e8 --- /dev/null +++ b/chalk/ui/kis_tool_dummy.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2004 Adrian Page <adrian@pagenet.plus.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_TOOL_DUMMY_H_ +#define KIS_TOOL_DUMMY_H_ + +#include "kis_tool_non_paint.h" +#include "kis_tool_factory.h" +#include <koffice_export.h> + +#include "kis_point.h" + +class TQLabel; +class KisCanvasSubject; + +/** + * The dummy tool is activated when a layer does not permit painting + * or any other destructive action. It shows a forbidden cursor, making + * it clear that you really cannot do anything here. + * + * Furthermore, it implements more or less the same things as the pan tool, + * so we can at least move the canvas around. + */ +class KRITATOOL_EXPORT KisToolDummy : public KisToolNonPaint { + + typedef KisToolNonPaint super; + Q_OBJECT + TQ_OBJECT + +public: + KisToolDummy(); + virtual ~KisToolDummy(); + + virtual void update(KisCanvasSubject *subject); + + virtual void setup(KActionCollection *collection); + virtual void buttonPress(KisButtonPressEvent *e); + virtual void move(KisMoveEvent *e); + virtual void buttonRelease(KisButtonReleaseEvent *e); + + virtual TQWidget* createOptionWidget(TQWidget* tqparent); + virtual TQWidget* optionWidget(); + +private: + TQLabel * m_optionWidget; + KisCanvasSubject *m_subject; + KisPoint m_dragPos; + TQ_INT32 m_origScrollX; + TQ_INT32 m_origScrollY; + bool m_dragging; +}; + +class KisToolDummyFactory : public KisToolFactory { + typedef KisToolFactory super; +public: + KisToolDummyFactory() : super() {}; + virtual ~KisToolDummyFactory() {}; + + virtual KisTool * createTool(KActionCollection * ac) { + KisTool * t = new KisToolDummy(); + Q_CHECK_PTR(t); + t->setup(ac); + return t; + } + virtual KisID id() { return KisID("dummy", i18n("Dummy Tool")); } +}; + + +#endif // KIS_TOOL_DUMMY_H_ + diff --git a/chalk/ui/kis_tool_factory.h b/chalk/ui/kis_tool_factory.h new file mode 100644 index 00000000..da1239e3 --- /dev/null +++ b/chalk/ui/kis_tool_factory.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_TOOL_FACTORY_H_ +#define KIS_TOOL_FACTORY_H_ + +#include <klocale.h> + +#include "kis_id.h" +#include "kis_types.h" +#include "kactioncollection.h" + +class KisToolFactory : public KShared +{ + +public: + KisToolFactory() {} + virtual ~KisToolFactory() {}; + + virtual KisTool * createTool(KActionCollection * ac) = 0; + virtual KisID id() { return KisID("Abstract Tool", i18n("Abstract Tool")); } + +}; + +#endif // KIS_TOOL_FACTORY_H_ + diff --git a/chalk/ui/kis_tool_freehand.cc b/chalk/ui/kis_tool_freehand.cc new file mode 100644 index 00000000..fe30eb50 --- /dev/null +++ b/chalk/ui/kis_tool_freehand.cc @@ -0,0 +1,354 @@ +/* + * kis_tool_brush.cc - part of Chalk + * + * Copyright (c) 2003-2004 Boudewijn Rempt <boud@valdyas.org> + * Copyright (c) 2004 Bart Coppens <kde@bartcoppens.be> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include <tqevent.h> +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqwidget.h> +#include <tqrect.h> + +#include <kdebug.h> +#include <kaction.h> +#include <kcommand.h> +#include <klocale.h> + +#include "kis_canvas_subject.h" +#include "kis_undo_adapter.h" +#include "kis_selection.h" +#include "kis_painter.h" +#include "kis_fill_painter.h" +#include "kis_tool_freehand.h" +#include "kis_cursor.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_move_event.h" +#include "kis_layer.h" +#include "kis_group_layer.h" +#include "kis_paint_layer.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_boundary_painter.h" +#include "kis_brush.h" + +KisToolFreehand::KisToolFreehand(TQString transactionText) + : super(transactionText), + m_dragDist ( 0 ), + m_transactionText(transactionText), + m_mode( HOVER ) +{ + m_painter = 0; + m_currentImage = 0; + m_tempLayer = 0; + m_paintIncremental = true; + m_paintOnSelection = false; + m_paintedOutline = false; +} + +KisToolFreehand::~KisToolFreehand() +{ +} + +void KisToolFreehand::update(KisCanvasSubject *subject) +{ + super::update(subject); + m_currentImage = m_subject->currentImg(); +} + +void KisToolFreehand::buttonPress(KisButtonPressEvent *e) +{ + if (!m_subject) return; + + if (!m_subject->currentBrush()) return; + + if (!m_currentImage || !m_currentImage->activeDevice()) return; + + if (e->button() == Qt::LeftButton) { + + m_currentImage->activeDevice()->lock( true ); + kdDebug() << ">>>>>>>>>>>>>>>>>>>Locking paint device\n"; + + // People complain that they can't start brush strokes outside of the image boundaries. + // This makes sense, especially when combined with BUG:132759, so commenting out the + // next line makes sense. + //if (!m_currentImage->bounds().tqcontains(e->pos().floorTQPoint())) return; + + initPaint(e); + paintAt(e->pos(), e->pressure(), e->xTilt(), e->yTilt()); + + m_prevPos = e->pos(); + m_prevPressure = e->pressure(); + m_prevXTilt = e->xTilt(); + m_prevYTilt = e->yTilt(); + + TQRect r = m_painter->dirtyRect(); + if ( r.isValid() ) { + m_dirtyRect = r; + + r = TQRect(r.left()-1, r.top()-1, r.width()+2, r.height()+2); //needed to update selectionvisualization + if (!m_paintOnSelection) { + m_currentImage->activeLayer()->setDirty(r); + } + else { + m_target->setDirty(r); + // Just update the canvas. XXX: After 1.5, find a better way to make sure tools don't set dirty what they didn't touch. + m_subject->canvasController()->updateCanvas( r ); + } + } + } +} + +void KisToolFreehand::buttonRelease(KisButtonReleaseEvent* e) +{ + if (e->button() == Qt::LeftButton && m_mode == PAINT) { + endPaint(); + m_currentImage->activeDevice()->lock( false ); + kdDebug() << ">>>>>>>>>>>>>>>>>>>UNLocking paint device\n"; + + } + KisToolPaint::buttonRelease(e); +} + +void KisToolFreehand::move(KisMoveEvent *e) +{ + if (m_mode == PAINT) { + + paintLine(m_prevPos, m_prevPressure, m_prevXTilt, m_prevYTilt, e->pos(), e->pressure(), e->xTilt(), e->yTilt()); + + m_prevPos = e->pos(); + m_prevPressure = e->pressure(); + m_prevXTilt = e->xTilt(); + m_prevYTilt = e->yTilt(); + + TQRect r = m_painter->dirtyRect(); + + if (r.isValid()) { + m_dirtyRect |= r; + + if (!m_paintOnSelection) { + m_currentImage->activeLayer()->setDirty(r); + } + else { + // Just update the canvas + r = TQRect(r.left()-1, r.top()-1, r.width()+2, r.height()+2); //needed to update selectionvisualization + m_target->setDirty(r); + m_subject->canvasController()->updateCanvas( r ); + } + } + } +} + +void KisToolFreehand::initPaint(KisEvent *) +{ + if (!m_currentImage || !m_currentImage->activeDevice()) return; + + m_mode = PAINT; + m_dragDist = 0; + + // Create painter + KisPaintDeviceSP device; + if (m_currentImage && (device = m_currentImage->activeDevice())) { + + if (m_painter) + delete m_painter; + + if (!m_paintIncremental) { + if (m_currentImage->undo()) + m_currentImage->undoAdapter()->beginMacro(m_transactionText); + + KisLayerSupportsIndirectPainting* layer; + if ((layer = dynamic_cast<KisLayerSupportsIndirectPainting*>( + m_currentImage->activeLayer().data()))) { + + // Hack for the painting of single-layered layers using indirect painting, + // because the group layer would not have a correctly synched cache ( + // because of an optimization that would happen, having this layer as + // projection). + KisLayer* l = layer->layer(); + KisPaintLayer* pl = dynamic_cast<KisPaintLayer*>(l); + if (l->tqparent() && (l->tqparent()->tqparent() == 0) + && (l->tqparent()->childCount() == 1) + && l->tqparent()->paintLayerInducesProjectionOptimization(pl)) { + // If there's a tqmask, device could've been the tqmask. The induce function + // should catch this, but better safe than sorry + l->tqparent()->resetProjection(pl->paintDevice()); + } + + m_target = new KisPaintDevice(m_currentImage->activeLayer(), + device->colorSpace()); + layer->setTemporaryTarget(m_target); + layer->setTemporaryCompositeOp(m_compositeOp); + layer->setTemporaryOpacity(m_opacity); + + if (device->hasSelection()) + m_target->setSelection(device->selection()); + } + } else { + m_target = device; + } + if(m_target->hasSelection()) m_target->selection()->startCachingExactRect(); + m_painter = new KisPainter( m_target ); + Q_CHECK_PTR(m_painter); + m_source = device; + if (currentImage()->undo()) m_painter->beginTransaction(m_transactionText); + } + + m_painter->setPaintColor(m_subject->fgColor()); + m_painter->setBackgroundColor(m_subject->bgColor()); + m_painter->setBrush(m_subject->currentBrush()); + + + // if you're drawing on a temporary layer, the layer already sets this + if (m_paintIncremental) { + m_painter->setCompositeOp(m_compositeOp); + m_painter->setOpacity(m_opacity); + } else { + m_painter->setCompositeOp(COMPOSITE_ALPHA_DARKEN); + m_painter->setOpacity( OPACITY_OPAQUE ); + + } + +/* kdDebug() << "target: " << m_target << "( " << m_target->name() << " )" + << " source: " << m_source << "( " << m_source->name() << " )" + << ", incremental " << m_paintIncremental + << ", paint on selection: " << m_paintOnSelection + << ", active device has selection: " << device->hasSelection() + << ", target has selection: " << m_target->hasSelection() + << endl; +*/ +} + +void KisToolFreehand::endPaint() +{ + m_mode = HOVER; + if (m_currentImage) { + + if (m_painter) { + // If painting in mouse release, make sure painter + // is destructed or end()ed + if (!m_paintIncremental) { + if (m_currentImage->undo()) + m_painter->endTransaction(); + KisPainter painter( m_source ); + painter.setCompositeOp(m_compositeOp); + if (m_currentImage->undo()) + painter.beginTransaction(m_transactionText); + painter.bitBlt(m_dirtyRect.x(), m_dirtyRect.y(), m_compositeOp, m_target, + m_opacity, + m_dirtyRect.x(), m_dirtyRect.y(), + m_dirtyRect.width(), m_dirtyRect.height()); + + KisLayerSupportsIndirectPainting* layer = + dynamic_cast<KisLayerSupportsIndirectPainting*>(m_source->tqparentLayer()); + layer->setTemporaryTarget(0); + m_source->tqparentLayer()->setDirty(m_dirtyRect); + + if (m_currentImage->undo()) { + m_currentImage->undoAdapter()->addCommand(painter.endTransaction()); + m_currentImage->undoAdapter()->endMacro(); + } + } else { + if (m_currentImage->undo()) + m_currentImage->undoAdapter()->addCommand(m_painter->endTransaction()); + } + } + delete m_painter; + m_painter = 0; + notifyModified(); + if(m_target->hasSelection()) m_target->selection()->stopCachingExactRect(); + } +} + +void KisToolFreehand::paintAt(const KisPoint &pos, + const double pressure, + const double xTilt, + const double yTilt) +{ + painter()->paintAt(pos, pressure, xTilt, yTilt); +} + +void KisToolFreehand::paintLine(const KisPoint & pos1, + const double pressure1, + const double xtilt1, + const double ytilt1, + const KisPoint & pos2, + const double pressure2, + const double xtilt2, + const double ytilt2) +{ + m_dragDist = painter()->paintLine(pos1, pressure1, xtilt1, ytilt1, pos2, pressure2, xtilt2, ytilt2, m_dragDist); +} + + +KisImageSP KisToolFreehand::currentImage() +{ + return m_currentImage; +} + + +void KisToolFreehand::paintOutline(const KisPoint& point) { + if (!m_subject) { + return; + } + + KisCanvasController *controller = m_subject->canvasController(); + + if (currentImage() && !currentImage()->bounds().tqcontains(point.floorTQPoint())) { + if (m_paintedOutline) { + controller->kiscanvas()->update(); + m_paintedOutline = false; + } + return; + } + + KisCanvas *canvas = controller->kiscanvas(); + canvas->tqrepaint(); + + KisBrush *brush = m_subject->currentBrush(); + // There may not be a brush present, and we shouldn't crash in that case + if (brush) { + KisCanvasPainter gc(canvas); + TQPen pen(TQt::SolidLine); + + KisPoint hotSpot = brush->hotSpot(); + + gc.setRasterOp(TQt::NotROP); + gc.setPen(pen); + gc.setViewport(0, 0, static_cast<TQ_INT32>(canvas->width() * m_subject->zoomFactor()), + static_cast<TQ_INT32>(canvas->height() * m_subject->zoomFactor())); + gc.translate((- controller->horzValue()) / m_subject->zoomFactor(), + (- controller->vertValue()) / m_subject->zoomFactor()); + + KisPoint topLeft = point - hotSpot; + + if (m_subject->currentPaintop().id() == "pen") { + // Pen paints on whole pixels only. + topLeft = topLeft.roundTQPoint(); + } + + gc.translate(topLeft.x(), topLeft.y()); + + KisBoundaryPainter::paint(brush->boundary(), gc); + m_paintedOutline = true; + } +} + + +#include "kis_tool_freehand.moc" + diff --git a/chalk/ui/kis_tool_freehand.h b/chalk/ui/kis_tool_freehand.h new file mode 100644 index 00000000..91db5698 --- /dev/null +++ b/chalk/ui/kis_tool_freehand.h @@ -0,0 +1,103 @@ +/* + * kis_tool_brush.h - part of Chalk + * + * Copyright (c) 2003-2004 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_TOOL_FREEHAND_H_ +#define KIS_TOOL_FREEHAND_H_ + +#include "kis_types.h" +#include "kis_tool_paint.h" +#include "kis_point.h" +#include "koffice_export.h" + +class KisPainter; +class KisBrush; +class KisEvent; +class KisPaintLayer; + + +class KRITACORE_EXPORT KisToolFreehand : public KisToolPaint { + Q_OBJECT + TQ_OBJECT + typedef KisToolPaint super; + +public: + KisToolFreehand(const TQString transactionText); + virtual ~KisToolFreehand(); + + virtual void update(KisCanvasSubject *subject); + + virtual void buttonPress(KisButtonPressEvent *e); + virtual void move(KisMoveEvent *e); + virtual void buttonRelease(KisButtonReleaseEvent *e); + + virtual enumToolType toolType() { return TOOL_FREEHAND; } + +protected: + virtual void paintAt(const KisPoint &pos, + const double pressure, + const double xTilt, + const double yTilt); + + virtual void paintLine(const KisPoint & pos1, + const double pressure1, + const double xtilt1, + const double ytilt1, + const KisPoint & pos2, + const double pressure2, + const double xtilt2, + const double ytilt2); + + // XXX: why not make this a protected member attribute for the + // use of subclasses? BSAR. + inline KisPainter * painter() { return m_painter; }; + virtual void initPaint(KisEvent *e); + virtual void endPaint(); + + KisImageSP currentImage(); + + void paintOutline(const KisPoint& point); + +protected: + KisPoint m_prevPos; + double m_prevPressure; + double m_prevXTilt; + double m_prevYTilt; + double m_dragDist; + + bool m_paintIncremental; + bool m_paintOnSelection; + + KisPaintDeviceSP m_target; + KisLayerSP m_tempLayer; + KisPaintDeviceSP m_source; + + TQString m_transactionText; + enumBrushMode m_mode; + KisPainter *m_painter; + + KisImageSP m_currentImage; +private: + bool m_paintedOutline; +}; + + + +#endif // KIS_TOOL_FREEHAND_H_ + diff --git a/chalk/ui/kis_tool_manager.cc b/chalk/ui/kis_tool_manager.cc new file mode 100644 index 00000000..456c60a7 --- /dev/null +++ b/chalk/ui/kis_tool_manager.cc @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "kopalettemanager.h" + +#include "kis_part_layer.h" +#include "kis_tool_manager.h" +#include "kis_tool_registry.h" +#include "kis_tool_dummy.h" +#include "kis_canvas_subject.h" +#include "kis_tool_controller.h" +#include "kis_view.h" +#include "kis_canvas.h" +#include "kis_cursor.h" +#include "KoToolBox.h" +#include "kis_image.h" +#include "kis_layer.h" +#include "kis_input_device.h" + + +KisToolManager::KisToolManager(KisCanvasSubject * tqparent, KisCanvasController * controller) + : m_subject(tqparent), + m_controller(controller) +{ + m_toolBox = 0; + m_oldTool = 0; + m_dummyTool = 0; + m_paletteManager = 0; + m_actionCollection = 0; + m_tools_disabled = false; + setup = false; +} + +KisToolManager::~KisToolManager() +{ + delete m_dummyTool; +} + +void KisToolManager::setUp(KoToolBox * toolbox, KoPaletteManager * paletteManager, KActionCollection * actionCollection) +{ + if (setup) { + resetToolBox( toolbox ); + return; + } + + m_toolBox = toolbox; + m_paletteManager = paletteManager; + m_actionCollection = actionCollection; + + // Dummy tool for when the layer is locked or invisible + if (!m_dummyTool) + m_dummyTool = KisToolDummyFactory().createTool(actionCollection); + + TQValueVector<KisInputDevice> inputDevices = KisInputDevice::inputDevices(); + + for (TQ_UINT32 inputDevice = 0; inputDevice < inputDevices.count(); inputDevice++) { + m_inputDeviceToolSetMap[inputDevices[inputDevice]] = KisToolRegistry::instance()->createTools(actionCollection, m_subject); + } + + m_tools = m_inputDeviceToolSetMap[KisInputDevice::mouse()]; + for (vKisTool_it it = m_tools.begin(); it != m_tools.end(); ++it) { + KisTool * t = *it; + if (!t) continue; + toolbox->registerTool( t->action(), t->toolType(), t->priority() ); + } + + toolbox->setupTools(); + + KisTool * t = findTool("tool_brush"); + if (t) { + t->activate(); + setCurrentTool(t); + } + setup = true; + +} + + + +void KisToolManager::youAintGotNoToolBox() +{ + m_toolBox = 0; + m_oldTool = currentTool(); +} + +void KisToolManager::resetToolBox(KoToolBox * toolbox) +{ + m_toolBox = toolbox; + + m_tools = m_inputDeviceToolSetMap[KisInputDevice::mouse()]; + for (vKisTool_it it = m_tools.begin(); it != m_tools.end(); ++it) { + KisTool * t = *it; + if (!t) continue; + m_toolBox->registerTool( t->action(), t->toolType(), t->priority() ); + } + + toolbox->setupTools(); + +#if 0 // Because I cannot find out how to reset the toolbox so the button is depressed, we reset the tool to brush + setCurrentTool(findTool("tool_brush")); +#else + if (m_oldTool) { + // restore the old current tool + setCurrentTool(m_oldTool); + m_oldTool = 0; + } +#endif + +} + +void KisToolManager::updateGUI() +{ + Q_ASSERT(m_subject); + if (m_subject == 0) { + // "Eek, no tqparent! + return; + } + + if (!m_toolBox) return; + + KisImageSP img = m_subject->currentImg(); + KisLayerSP l = 0; + + bool enable = false; + + + KisPartLayer * partLayer = dynamic_cast<KisPartLayer*>(l.data()); + + if (img) { + l = img->activeLayer(); + enable = l && !l->locked() && l->visible() && (partLayer == 0); + } + + m_toolBox->enableTools( enable ); + + KisTool * current = currentTool(); + + // XXX: Fix this properly: changing the visibility of a layer causes this cause to be executed twice! + if (!enable && current != m_dummyTool) { + // Store the current tool + m_oldTool = currentTool(); + // Set the dummy tool + if (!m_dummyTool) { + m_dummyTool = KisToolDummyFactory().createTool(m_actionCollection); + } + setCurrentTool(m_dummyTool); + m_tools_disabled = true; + } + else if (enable && m_tools_disabled) { + m_tools_disabled = false; + if (m_oldTool) { + // restore the old current tool + setCurrentTool(m_oldTool); + m_oldTool = 0; + } + else { + m_oldTool = 0; + KisTool * t = findTool("tool_brush"); + setCurrentTool(t); + } + } +} + +void KisToolManager::setCurrentTool(KisTool *tool) +{ + KisTool *oldTool = currentTool(); + KisCanvas * canvas = (KisCanvas*)m_controller->kiscanvas(); + + + if (oldTool) + { + oldTool->deactivate(); + oldTool->action()->setChecked( false ); + + m_paletteManager->removeWidget(chalk::TOOL_OPTION_WIDGET); + } + + if (tool) { + + if (!tool->optionWidget()) { + tool->createOptionWidget(0); + } + TQWidget * w = tool->optionWidget(); + + if (w) + m_paletteManager->addWidget(w, chalk::TOOL_OPTION_WIDGET, chalk::CONTROL_PALETTE ); + + m_inputDeviceToolMap[m_controller->currentInputDevice()] = tool; + m_controller->setCanvasCursor(tool->cursor()); + + canvas->enableMoveEventCompressionHint(dynamic_cast<KisToolNonPaint *>(tool) != NULL); + + m_subject->notifyObservers(); + + tool->action()->setChecked( true ); + tool->action()->activate(); + m_toolBox->slotSetTool(tool->name()); + } else { + m_inputDeviceToolMap[m_controller->currentInputDevice()] = 0; + m_controller->setCanvasCursor(KisCursor::arrowCursor()); + } + +} + +void KisToolManager::setCurrentTool( const TQString & toolName ) +{ + setCurrentTool(findTool(toolName)); +} + +KisTool * KisToolManager::currentTool() const +{ + InputDeviceToolMap::const_iterator it = m_inputDeviceToolMap.find(m_controller->currentInputDevice()); + + if (it != m_inputDeviceToolMap.end()) { + return (*it).second; + } else { + return 0; + } +} + + +void KisToolManager::setToolForInputDevice(KisInputDevice oldDevice, KisInputDevice newDevice) +{ + InputDeviceToolSetMap::iterator vit = m_inputDeviceToolSetMap.find(oldDevice); + + if (vit != m_inputDeviceToolSetMap.end()) { + vKisTool& oldTools = (*vit).second; + for (vKisTool::iterator it = oldTools.begin(); it != oldTools.end(); ++it) { + KisTool *tool = *it; + KAction *toolAction = tool->action(); + toolAction->disconnect(TQT_SIGNAL(activated()), tool, TQT_SLOT(activate())); + } + } + KisTool *oldTool = currentTool(); + if (oldTool) + { + m_paletteManager->removeWidget(chalk::TOOL_OPTION_WIDGET); + oldTool->deactivate(); + } + + + vit = m_inputDeviceToolSetMap.find(newDevice); + + Q_ASSERT(vit != m_inputDeviceToolSetMap.end()); + + vKisTool& tools = (*vit).second; + + for (vKisTool::iterator it = tools.begin(); it != tools.end(); ++it) { + KisTool *tool = *it; + KAction *toolAction = tool->action(); + connect(toolAction, TQT_SIGNAL(activated()), tool, TQT_SLOT(activate())); + } +} + +void KisToolManager::activateCurrentTool() +{ + KisTool * t = currentTool(); + if (t && t->action()) { + t->action()->activate(); + } +} + +KisTool * KisToolManager::findTool(const TQString &toolName, KisInputDevice inputDevice) const +{ + if (inputDevice == KisInputDevice::unknown()) { + inputDevice = m_controller->currentInputDevice(); + } + + KisTool *tool = 0; + + InputDeviceToolSetMap::const_iterator vit = m_inputDeviceToolSetMap.find(inputDevice); + + Q_ASSERT(vit != m_inputDeviceToolSetMap.end()); + + const vKisTool& tools = (*vit).second; + + for (vKisTool::const_iterator it = tools.begin(); it != tools.end(); ++it) { + KisTool *t = *it; + if (t->name() == toolName) { + tool = t; + break; + } + } + + return tool; +} + + +#include "kis_tool_manager.moc" diff --git a/chalk/ui/kis_tool_manager.h b/chalk/ui/kis_tool_manager.h new file mode 100644 index 00000000..8f04f680 --- /dev/null +++ b/chalk/ui/kis_tool_manager.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_TOOL_MANAGER +#define KIS_TOOL_MANAGER + +#include <map> + +#include <tqobject.h> + +#include "kis_tool_controller.h" +#include "kis_global.h" +#include "kis_tool_types.h" +#include "kis_input_device.h" + +class KoView; +class KisCanvasSubject; +class KisView; +class KisTool; +class KisToolRegistry; +class KisCanvasController; +class KoPaletteManager; +class KoToolBox; + +/** + * This class manages the activation and deactivation of tools for + * each input device. + */ +class KisToolManager : public TQObject, public KisToolControllerInterface { + + Q_OBJECT + TQ_OBJECT + +public: + + KisToolManager(KisCanvasSubject * tqparent, KisCanvasController * controller); + ~KisToolManager(); + +public: + + void setUp(KoToolBox * toolbox, KoPaletteManager * paletteManager, KActionCollection * collection); + + // Called when the toolbox is deleted because the view was made inactive in favour of another view + void youAintGotNoToolBox(); + + void updateGUI(); + + virtual void setCurrentTool(KisTool *tool); + virtual void setCurrentTool(const TQString & toolName); + + virtual KisTool *currentTool() const; + + void setToolForInputDevice(KisInputDevice oldDevice, KisInputDevice newDevice); + + KisTool *findTool(const TQString &toolName, KisInputDevice inputDevice = KisInputDevice::unknown()) const; + + void activateCurrentTool(); + +private: + + void resetToolBox(KoToolBox * toolbox); + +private: + + typedef std::map<KisInputDevice, KisTool *> InputDeviceToolMap; + typedef std::map<KisInputDevice, vKisTool> InputDeviceToolSetMap; + + InputDeviceToolMap m_inputDeviceToolMap; + InputDeviceToolSetMap m_inputDeviceToolSetMap; + + KisCanvasSubject * m_subject; + KisCanvasController * m_controller; + + KoPaletteManager * m_paletteManager; + KActionCollection * m_actionCollection; + + KoToolBox * m_toolBox; + + KisTool * m_oldTool; + KisTool * m_dummyTool; + + vKisTool m_tools; + + bool m_tools_disabled; + bool setup; +}; + + +#endif diff --git a/chalk/ui/kis_tool_non_paint.cc b/chalk/ui/kis_tool_non_paint.cc new file mode 100644 index 00000000..4adccc60 --- /dev/null +++ b/chalk/ui/kis_tool_non_paint.cc @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2002 Patrick Julien <freak@codepimps.org> + * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <kdebug.h> + +#include "kis_image.h" +#include "kis_canvas_subject.h" +#include "kis_canvas_controller.h" +#include "kis_tool_controller.h" +#include "kis_tool_non_paint.h" + +KisToolNonPaint::KisToolNonPaint(const TQString & UIName) + : super(UIName) +{ + m_subject = 0; +} + +KisToolNonPaint::~KisToolNonPaint() +{ +} + +void KisToolNonPaint::update(KisCanvasSubject *subject) +{ + m_subject = subject; +} + +void KisToolNonPaint::paint(KisCanvasPainter&) +{ +} + +void KisToolNonPaint::paint(KisCanvasPainter&, const TQRect&) +{ +} + +void KisToolNonPaint::deactivate() +{ +} + +void KisToolNonPaint::buttonPress(KisButtonPressEvent *) +{ +} + +void KisToolNonPaint::move(KisMoveEvent *) +{ +} + +void KisToolNonPaint::buttonRelease(KisButtonReleaseEvent *) +{ +} + +void KisToolNonPaint::doubleClick(KisDoubleClickEvent *) +{ +} + +void KisToolNonPaint::keyPress(TQKeyEvent *) +{ +} + +void KisToolNonPaint::keyRelease(TQKeyEvent *) +{ +} + +TQCursor KisToolNonPaint::cursor() +{ + return m_cursor; +} + +void KisToolNonPaint::setCursor(const TQCursor& cursor) +{ + m_cursor = cursor; + + if (m_subject) { + KisToolControllerInterface *controller = m_subject->toolController(); + + if (controller && controller->currentTool() == this) { + m_subject->canvasController()->setCanvasCursor(m_cursor); + } + } +} + +void KisToolNonPaint::activate() +{ + if (m_subject) { + KisToolControllerInterface *controller = m_subject->toolController(); + + if (controller) + controller->setCurrentTool(this); + } +} + +void KisToolNonPaint::notifyModified() const +{ + if (m_subject && m_subject->currentImg()) { + + m_subject->currentImg()->setModified(); + } +} + +#include "kis_tool_non_paint.moc" diff --git a/chalk/ui/kis_tool_non_paint.h b/chalk/ui/kis_tool_non_paint.h new file mode 100644 index 00000000..0b618109 --- /dev/null +++ b/chalk/ui/kis_tool_non_paint.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2002 Patrick Julien <freak@codepimps.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_TOOL_NON_PAINT_H_ +#define KIS_TOOL_NON_PAINT_H_ + +#include <tqcursor.h> +#include <tqcolor.h> +#include <tqwidget.h> + +#include "kis_global.h" +#include "kis_types.h" +#include "kis_tool.h" +#include <koffice_export.h> + +class TQEvent; +class TQKeyEvent; +class TQPaintEvent; +class TQRect; +class KDialog; +class KisCanvasSubject; + + +class KRITACORE_EXPORT KisToolNonPaint : public KisTool { + + Q_OBJECT + TQ_OBJECT + typedef KisTool super; + +public: + KisToolNonPaint(const TQString & UIName); + virtual ~KisToolNonPaint(); + +// CanvasObserver +public: + virtual void update(KisCanvasSubject *subject); + +// KisTool +public: + virtual void paint(KisCanvasPainter& gc); + virtual void paint(KisCanvasPainter& gc, const TQRect& rc); + + virtual void buttonPress(KisButtonPressEvent *e); + virtual void move(KisMoveEvent *e); + virtual void buttonRelease(KisButtonReleaseEvent *e); + virtual void doubleClick(KisDoubleClickEvent *e); + virtual void keyPress(TQKeyEvent *e); + virtual void keyRelease(TQKeyEvent *e); + + virtual TQCursor cursor(); + virtual void setCursor(const TQCursor& cursor); + + virtual enumToolType toolType() { return TOOL_VIEW; } + +public slots: + virtual void activate(); + virtual void deactivate(); + +protected: + void notifyModified() const; + +protected: + KisCanvasSubject *m_subject; + +private: + TQCursor m_cursor; +}; + +#endif // KIS_TOOL_NON_PAINT_H_ + diff --git a/chalk/ui/kis_tool_paint.cc b/chalk/ui/kis_tool_paint.cc new file mode 100644 index 00000000..d8d19f36 --- /dev/null +++ b/chalk/ui/kis_tool_paint.cc @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2003 Boudewijn Rempt + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <tqwidget.h> +#include <tqrect.h> +#include <tqlayout.h> +#include <tqlabel.h> +#include <tqpushbutton.h> +#include <tqwhatsthis.h> +#include <tqcheckbox.h> + +#include <kdebug.h> +#include <klocale.h> +#include <knuminput.h> +#include <kiconloader.h> + +#include "kis_button_release_event.h" +#include "kis_canvas_subject.h" +#include "kis_cmb_composite.h" +#include "kis_colorspace.h" +#include "kis_config.h" +#include "kis_cursor.h" +#include "kis_global.h" +#include "kis_image.h" +#include "kis_int_spinbox.h" +#include "kis_paint_device.h" +#include "kis_tool_controller.h" +#include "kis_tool_paint.h" + +KisToolPaint::KisToolPaint(const TQString& UIName) + : super(UIName) +{ + m_subject = 0; + + m_UIName = UIName; + + m_optionWidget = 0; + m_optionWidgetLayout = 0; + + m_lbOpacity = 0; + m_slOpacity = 0; + m_lbComposite= 0; + m_cmbComposite = 0; + + m_opacity = OPACITY_OPAQUE; + m_compositeOp = COMPOSITE_OVER; +} + +KisToolPaint::~KisToolPaint() +{ +} + +void KisToolPaint::update(KisCanvasSubject *subject) +{ + m_subject = subject; + updateCompositeOpComboBox(); +} + +void KisToolPaint::paint(KisCanvasPainter&) +{ +} + +void KisToolPaint::paint(KisCanvasPainter&, const TQRect&) +{ +} + +void KisToolPaint::deactivate() +{ +} + +void KisToolPaint::buttonPress(KisButtonPressEvent *) +{ +} + +void KisToolPaint::move(KisMoveEvent *) +{ +} + +void KisToolPaint::buttonRelease(KisButtonReleaseEvent * e) +{ + kdDebug() << "buttonRelease" << endl; + if(e->button() == Qt::MidButton) + { + kdDebug() << "switch" << endl; + KisColor bg = m_subject->bgColor(); + m_subject->setBGColor(m_subject->fgColor()); + m_subject->setFGColor(bg); + } +} + +void KisToolPaint::doubleClick(KisDoubleClickEvent *) +{ +} + +void KisToolPaint::keyPress(TQKeyEvent *) +{ +} + +void KisToolPaint::keyRelease(TQKeyEvent *) +{ +} + +TQWidget* KisToolPaint::createOptionWidget(TQWidget* tqparent) +{ + m_optionWidget = new TQWidget(tqparent); + m_optionWidget->setCaption(m_UIName); + + m_lbOpacity = new TQLabel(i18n("Opacity:"), m_optionWidget); + m_slOpacity = new KisIntSpinbox( m_optionWidget, "int_m_optionwidget"); + m_slOpacity->setRange( 0, 100); + m_slOpacity->setValue(m_opacity / OPACITY_OPAQUE * 100); + connect(m_slOpacity, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(slotSetOpacity(int))); + + m_lbComposite = new TQLabel(i18n("Mode:"), m_optionWidget); + m_cmbComposite = new KisCmbComposite(m_optionWidget); + connect(m_cmbComposite, TQT_SIGNAL(activated(const KisCompositeOp&)), this, TQT_SLOT(slotSetCompositeMode(const KisCompositeOp&))); + + TQVBoxLayout* verticalLayout = new TQVBoxLayout(m_optionWidget); + verticalLayout->setMargin(0); + verticalLayout->setSpacing(3); + + m_optionWidgetLayout = new TQGridLayout(verticalLayout, 2, 3, 6); + + m_optionWidgetLayout->addWidget(m_lbOpacity, 0, 0); + m_optionWidgetLayout->addWidget(m_slOpacity, 0, 1); + + m_optionWidgetLayout->addWidget(m_lbComposite, 1, 0); + m_optionWidgetLayout->addWidget(m_cmbComposite, 1, 1); + + verticalLayout->addItem(new TQSpacerItem(0,0,TQSizePolicy::Fixed,TQSizePolicy::Expanding)); + + if (!quickHelp().isEmpty()) { + TQPushButton* push = new TQPushButton(SmallIconSet( "help" ), "", m_optionWidget); + connect(push, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotPopupQuickHelp())); + + TQHBoxLayout* hLayout = new TQHBoxLayout(m_optionWidget); + hLayout->addWidget(push); + hLayout->addItem(new TQSpacerItem(0,0,TQSizePolicy::Expanding,TQSizePolicy::Fixed)); + verticalLayout->addLayout(hLayout); + } + return m_optionWidget; +} + +TQWidget* KisToolPaint::optionWidget() +{ + return m_optionWidget; +} + +void KisToolPaint::addOptionWidgetLayout(TQLayout *tqlayout) +{ + Q_ASSERT(m_optionWidget != 0); + Q_ASSERT(m_optionWidgetLayout != 0); + int rowCount = m_optionWidgetLayout->numRows(); + m_optionWidgetLayout->addMultiCellLayout(tqlayout, rowCount, rowCount, 0, 1); +} + +void KisToolPaint::addOptionWidgetOption(TQWidget *control, TQWidget *label) +{ + Q_ASSERT(m_optionWidget != 0); + Q_ASSERT(m_optionWidgetLayout != 0); + if(label) + { + m_optionWidgetLayout->addWidget(label, m_optionWidgetLayout->numRows(), 0); + m_optionWidgetLayout->addWidget(control, m_optionWidgetLayout->numRows()-1, 1); + } + else + m_optionWidgetLayout->addMultiCellWidget(control, m_optionWidgetLayout->numRows(), m_optionWidgetLayout->numRows(), 0, 1); +} + +void KisToolPaint::slotSetOpacity(int opacityPerCent) +{ + m_opacity = opacityPerCent * OPACITY_OPAQUE / 100; +} + +void KisToolPaint::slotSetCompositeMode(const KisCompositeOp& compositeOp) +{ + m_compositeOp = compositeOp; +} + +TQCursor KisToolPaint::cursor() +{ + return m_cursor; +} + +void KisToolPaint::setCursor(const TQCursor& cursor) +{ + m_cursor = cursor; + + if (m_subject) { + KisToolControllerInterface *controller = m_subject->toolController(); + + if (controller && controller->currentTool() == this) { + m_subject->canvasController()->setCanvasCursor(m_cursor); + } + } +} + +void KisToolPaint::activate() +{ + if (m_subject) { + KisToolControllerInterface *controller = m_subject->toolController(); + + if (controller) + controller->setCurrentTool(this); + + updateCompositeOpComboBox(); + + KisConfig cfg; + m_paintOutline = (cfg.cursorStyle() == CURSOR_STYLE_OUTLINE); + } +} + +void KisToolPaint::notifyModified() const +{ + if (m_subject && m_subject->currentImg()) { + m_subject->currentImg()->setModified(); + } +} + +void KisToolPaint::updateCompositeOpComboBox() +{ + if (m_optionWidget && m_subject) { + KisImageSP img = m_subject->currentImg(); + + if (img) { + KisPaintDeviceSP device = img->activeDevice(); + + if (device) { + KisCompositeOpList compositeOps = device->colorSpace()->userVisiblecompositeOps(); + m_cmbComposite->setCompositeOpList(compositeOps); + + if (compositeOps.tqfind(m_compositeOp) == compositeOps.end()) { + m_compositeOp = COMPOSITE_OVER; + } + m_cmbComposite->setCurrentItem(m_compositeOp); + } + } + } +} + +void KisToolPaint::slotPopupQuickHelp() { + TQWhatsThis::display(quickHelp()); +} + +#include "kis_tool_paint.moc" diff --git a/chalk/ui/kis_tool_paint.h b/chalk/ui/kis_tool_paint.h new file mode 100644 index 00000000..6e1406b5 --- /dev/null +++ b/chalk/ui/kis_tool_paint.h @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2003 Boudewijn Rempt + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_TOOL_PAINT_H_ +#define KIS_TOOL_PAINT_H_ + +#include <tqcursor.h> +#include <tqlayout.h> + +#include <koffice_export.h> + +#include "kis_tool.h" +#include "kis_composite_op.h" + +class TQCheckBox; +class TQEvent; +class TQKeyEvent; +class TQComboBox; +class TQPaintEvent; +class TQRect; +class TQGridLayout; +class KDialog; +class KisCanvasSubject; +class TQLabel; +class KisCmbComposite; +class KisIntSpinbox; + +enum enumBrushMode { + PAINT, + PAINT_STYLUS, + ERASE, + ERASE_STYLUS, + HOVER +}; + +class KRITACORE_EXPORT KisToolPaint : public KisTool { + + Q_OBJECT + TQ_OBJECT + typedef KisTool super; + +public: + KisToolPaint(const TQString& UIName); + virtual ~KisToolPaint(); + +public: + virtual void update(KisCanvasSubject *subject); + + virtual void paint(KisCanvasPainter& gc); + virtual void paint(KisCanvasPainter& gc, const TQRect& rc); + + virtual void buttonPress(KisButtonPressEvent *e); + virtual void move(KisMoveEvent *e); + virtual void buttonRelease(KisButtonReleaseEvent *e); + virtual void doubleClick(KisDoubleClickEvent *e); + virtual void keyPress(TQKeyEvent *e); + virtual void keyRelease(TQKeyEvent *e); + + virtual TQCursor cursor(); + virtual void setCursor(const TQCursor& cursor); + virtual TQWidget* createOptionWidget(TQWidget* tqparent); + virtual TQWidget* optionWidget(); + virtual void addOptionWidgetOption(TQWidget *control, TQWidget *label = 0); + +public slots: + virtual void activate(); + virtual void deactivate(); + + void slotSetOpacity(int opacityPerCent); + void slotSetCompositeMode(const KisCompositeOp& compositeOp); + void slotPopupQuickHelp(); + +protected: + void notifyModified() const; + + // Add the tool-specific tqlayout to the default option widget's tqlayout. + void addOptionWidgetLayout(TQLayout *tqlayout); + +private: + void updateCompositeOpComboBox(); + +protected: + KisCanvasSubject *m_subject; + TQRect m_dirtyRect; + TQ_UINT8 m_opacity; + KisCompositeOp m_compositeOp; + bool m_paintOutline; + +private: + TQString m_UIName; + + TQCursor m_cursor; + + TQWidget *m_optionWidget; + TQGridLayout *m_optionWidgetLayout; + + TQLabel *m_lbOpacity; + KisIntSpinbox *m_slOpacity; + TQLabel *m_lbComposite; + KisCmbComposite *m_cmbComposite; +}; + +#endif // KIS_TOOL_PAINT_H_ + diff --git a/chalk/ui/kis_tool_registry.cc b/chalk/ui/kis_tool_registry.cc new file mode 100644 index 00000000..e7696f0b --- /dev/null +++ b/chalk/ui/kis_tool_registry.cc @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kdebug.h" +#include <kaction.h> +#include <kparts/plugin.h> +#include <kservice.h> +#include <ktrader.h> +#include <kparts/componentfactory.h> + +#include "kis_generic_registry.h" +#include "kis_types.h" +#include "kis_tool_registry.h" +#include "kis_tool.h" +#include "kis_tool_factory.h" +#include "kis_canvas_subject.h" +#include "kis_id.h" +#include "kis_debug_areas.h" + +KisToolRegistry *KisToolRegistry::m_singleton = 0; + +KisToolRegistry::KisToolRegistry() +{ + // Load all modules: color models, paintops, filters + KTrader::OfferList offers = KTrader::self()->query(TQString::tqfromLatin1("Chalk/Tool"), + TQString::tqfromLatin1("(Type == 'Service') and " + "([X-Chalk-Version] == 2)")); + + KTrader::OfferList::ConstIterator iter; + + for(iter = offers.begin(); iter != offers.end(); ++iter) + { + KService::Ptr service = *iter; + int errCode = 0; + KParts::Plugin* plugin = + KParts::ComponentFactory::createInstanceFromService<KParts::Plugin> ( service, this, 0, TQStringList(), &errCode); + if ( plugin ) + kdDebug(DBG_AREA_PLUGINS) << "found plugin " << service->property("Name").toString() << "\n"; + else { + kdDebug(41006) << "found plugin " << service->property("Name").toString() << ", " << errCode << "\n"; + if( errCode == KParts::ComponentFactory::ErrNoLibrary) + { + kdWarning(41006) << " Error loading plugin was : ErrNoLibrary " << KLibLoader::self()->lastErrorMessage() << endl; + } + } + + } + +} + +KisToolRegistry::~KisToolRegistry() +{ +} + +KisToolRegistry* KisToolRegistry::instance() +{ + if(KisToolRegistry::m_singleton == 0) + { + KisToolRegistry::m_singleton = new KisToolRegistry(); + } + return KisToolRegistry::m_singleton; +} + + + +vKisTool KisToolRegistry::createTools(KActionCollection * ac, KisCanvasSubject *subject) const +{ + Q_ASSERT(subject); + + vKisTool tools; + + KisIDList factories = listKeys(); + + for (KisIDList::Iterator it = factories.begin(); it != factories.end(); ++it ) + { + KisToolFactorySP f = get(*it); + + KisTool * tool = f->createTool(ac); + subject->attach(tool); + tools.push_back(tool); + } + + subject->notifyObservers(); + + return tools; +} + +KisTool * KisToolRegistry::createTool(KActionCollection * ac, KisCanvasSubject * subject, KisID & id) const +{ + KisToolFactorySP f = get(id); + KisTool * t = f->createTool(ac); + subject->attach(t); + return t; +} + +#include "kis_tool_registry.moc" diff --git a/chalk/ui/kis_tool_registry.h b/chalk/ui/kis_tool_registry.h new file mode 100644 index 00000000..5fd32b93 --- /dev/null +++ b/chalk/ui/kis_tool_registry.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_TOOL_REGISTRY_H_ +#define KIS_TOOL_REGISTRY_H_ + +#include <tqobject.h> + +#include "kis_tool_types.h" +#include "kis_generic_registry.h" +#include <koffice_export.h> + +class KActionCollection; +class KisCanvasSubject; +class TQStringList; + +/** + * A registry, similar to the tool and colormodel registry + * where new tool plugins can register themselves. KisToolRegistry + * in contrast to the paintop and colormodel registries, creates + * a vector containing instances of all registered tools. + */ +class KRITACORE_EXPORT KisToolRegistry : public TQObject, public KisGenericRegistry<KisToolFactorySP>{ + + Q_OBJECT + TQ_OBJECT + +public: + virtual ~KisToolRegistry(); + + static KisToolRegistry* instance(); + + vKisTool createTools(KActionCollection * ac, KisCanvasSubject *subject) const; + KisTool * createTool(KActionCollection * ac, KisCanvasSubject * subject, KisID & id) const; + +private: + KisToolRegistry(); + KisToolRegistry(const KisToolRegistry&); + KisToolRegistry operator=(const KisToolRegistry&); + + static KisToolRegistry *m_singleton; +}; + +#endif // KIS_TOOL_REGISTRY_H_ + diff --git a/chalk/ui/kis_tool_shape.cc b/chalk/ui/kis_tool_shape.cc new file mode 100644 index 00000000..b919a578 --- /dev/null +++ b/chalk/ui/kis_tool_shape.cc @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2005 Adrian Page + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <tqwidget.h> +#include <tqlayout.h> +#include <tqcombobox.h> +#include <tqlabel.h> + +#include <kdebug.h> +#include <klocale.h> + +#include "kis_tool_shape.h" +#include "wdgshapeoptions.h" + +KisToolShape::KisToolShape(const TQString& UIName) : super(UIName) +{ + m_tqshapeOptionsWidget = 0; + m_optionLayout = 0; +} + +KisToolShape::~KisToolShape() +{ +} + +TQWidget* KisToolShape::createOptionWidget(TQWidget* tqparent) +{ + TQWidget *widget = super::createOptionWidget(tqparent); + + m_tqshapeOptionsWidget = new WdgGeometryOptions(0); + Q_CHECK_PTR(m_tqshapeOptionsWidget); + + m_optionLayout = new TQGridLayout(widget, 2, 1); + // super::addOptionWidgetLayout(m_optionLayout); + + m_tqshapeOptionsWidget->cmbFill->reparent(widget, TQPoint(0,0), true); + m_tqshapeOptionsWidget->textLabel3->reparent(widget, TQPoint(0,0), true); + addOptionWidgetOption(m_tqshapeOptionsWidget->cmbFill, m_tqshapeOptionsWidget->textLabel3); + + return widget; +} + +KisPainter::FillStyle KisToolShape::fillStyle(void) +{ + if (m_tqshapeOptionsWidget) { + return static_cast<KisPainter::FillStyle>(m_tqshapeOptionsWidget->cmbFill->currentItem()); + } else { + return KisPainter::FillStyleNone; + } +} + +#include "kis_tool_shape.moc" + diff --git a/chalk/ui/kis_tool_shape.h b/chalk/ui/kis_tool_shape.h new file mode 100644 index 00000000..2c0a9500 --- /dev/null +++ b/chalk/ui/kis_tool_shape.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2005 Adrian Page + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_TOOL_SHAPE_H_ +#define KIS_TOOL_SHAPE_H_ + +#include <koffice_export.h> + +#include "kis_tool_paint.h" +#include "kis_painter.h" + +class TQGridLayout; +class WdgGeometryOptions; + +class KRITACORE_EXPORT KisToolShape : public KisToolPaint { + + Q_OBJECT + TQ_OBJECT + typedef KisToolPaint super; + +public: + KisToolShape(const TQString& UIName); + virtual ~KisToolShape(); + + virtual enumToolType toolType() { return TOOL_SHAPE; } + +protected: + virtual TQWidget* createOptionWidget(TQWidget* tqparent); + + KisPainter::FillStyle fillStyle(); + +private: + TQGridLayout *m_optionLayout; + WdgGeometryOptions *m_tqshapeOptionsWidget; +}; + +#endif // KIS_TOOL_SHAPE_H_ + diff --git a/chalk/ui/kis_tool_types.h b/chalk/ui/kis_tool_types.h new file mode 100644 index 00000000..4811f75e --- /dev/null +++ b/chalk/ui/kis_tool_types.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_TOOL_TYPES_H_ +#define KIS_TOOL_TYPES_H_ + +#include <ksharedptr.h> +#include "kis_shared_ptr_vector.h" + + +class KisTool; +typedef KSharedPtr<KisTool> KisToolSP; +typedef KisSharedPtrVector<KisTool> vKisTool; +typedef vKisTool::iterator vKisTool_it; +typedef vKisTool::const_iterator vKisTool_cit; + +class KisToolFactory; +typedef KSharedPtr<KisToolFactory> KisToolFactorySP; + +#endif // KIS_TOOL_TYPES_H_ diff --git a/chalk/ui/kis_view.cc b/chalk/ui/kis_view.cc new file mode 100644 index 00000000..a146ddcb --- /dev/null +++ b/chalk/ui/kis_view.cc @@ -0,0 +1,4018 @@ +/* This file is part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 1999 Matthias Elter <me@kde.org> + * 1999 Michael Koch <koch@kde.org> + * 1999 Carsten Pfeiffer <pfeiffer@kde.org> + * 2002 Patrick Julien <freak@codepimps.org> + * 2003-2005 Boudewijn Rempt <boud@valdyas.org> + * 2004 Clarence Dang <dang@kde.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <algorithm> +#include <cmath> + +// TQt +#include <tqapplication.h> +#include <tqbutton.h> +#include <tqcursor.h> +#include <tqevent.h> +#include <tqpainter.h> +#include <tqscrollbar.h> +#include <tqspinbox.h> +#include <tqdockarea.h> +#include <tqstringlist.h> +#include <tqstyle.h> +#include <tqpopupmenu.h> +#include <tqvaluelist.h> +#include <tqstringlist.h> +#include <tqobjectlist.h> + +// KDE +#include <kis_meta_registry.h> +#include <kglobalsettings.h> +#include <dcopobject.h> +#include <kaction.h> +#include <kcolordialog.h> +#include <kiconloader.h> +#include <kfiledialog.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <knotifyclient.h> +#include <kprinter.h> +#include <kpushbutton.h> +#include <kstatusbar.h> +#include <kstdaction.h> +#include <kinputdialog.h> +#include <kurldrag.h> +#include <kpopupmenu.h> +#include <kdebug.h> +#include <ksharedptr.h> +#include <ktoolbar.h> +#include <kparts/plugin.h> +#include <kservice.h> +#include <ktrader.h> +#include <kparts/componentfactory.h> +#include <kparts/event.h> + +// KOffice +#include <KoPartSelectAction.h> +#include <KoFilterManager.h> +#include <KoMainWindow.h> +#include <KoView.h> +#include <KoTabBar.h> +#include <ko_gray_widget.h> +#include <ko_hsv_widget.h> +#include <ko_rgb_widget.h> +#include <kopalettemanager.h> +#include <kopalette.h> + +// Local +#include "kis_brush.h" +#include "kis_button_press_event.h" +#include "kis_button_release_event.h" +#include "kis_canvas.h" +#include "kis_canvas_painter.h" +#include "kis_color.h" +#include "kis_colorspace_factory_registry.h" +#include "kis_config.h" +#include "kis_controlframe.h" +#include "kis_cursor.h" +#include "kis_doc.h" +#include "kis_double_click_event.h" +#include "kis_factory.h" +#include "kis_filter_strategy.h" +#include "kis_gradient.h" +#include "kis_group_layer.h" +#include "kis_adjustment_layer.h" +#include "kis_paint_device.h" +#include "kis_tool_freehand.h" +//#include "kis_guide.h" +#include "kis_layerbox.h" +#include "kis_import_catcher.h" +#include "kis_layer.h" +#include "kis_paint_layer.h" +#include "kis_move_event.h" +#include "kis_paint_device.h" +#include "kis_painter.h" +#include "kis_paintop_registry.h" +#include "kis_part_layer.h" +#include "kis_part_layer_handler.h" +#include "kis_pattern.h" +#include "kis_profile.h" +#include "kis_rect.h" +#include "kis_resource.h" +#include "kis_palette.h" +#include "kis_ruler.h" +#include "kis_selection.h" +#include "KoToolBox.h" +#include "kis_tool.h" +#include "kis_tool_manager.h" +#include "kis_transaction.h" +#include "kis_selected_transaction.h" +#include "kis_types.h" +#include "kis_undo_adapter.h" +#include "kis_view.h" +#include "kis_view_iface.h" +#include "kis_label_progress.h" +#include "kis_opengl_image_context.h" +#include "kis_background.h" +#include "kis_paint_device_action.h" +#include "kis_filter_configuration.h" +#include "kis_transform_worker.h" +#include "kis_shear_visitor.h" + +#include <kis_resourceserver.h> +#include <kis_resource_mediator.h> + +#include "kis_icon_item.h" +#include "kis_palette_widget.h" +#include "kis_birdeye_box.h" +#include "kis_color.h" +#include "kis_factory.h" + +// Dialog boxes +#include "kis_dlg_new_layer.h" +#include "kis_dlg_layer_properties.h" +#include "kis_dlg_preferences.h" +#include "kis_dlg_image_properties.h" +#include "kis_dlg_adjustment_layer.h" +#include "kis_dlg_adj_layer_props.h" + +// Action managers +#include "kis_selection_manager.h" +#include "kis_filter_manager.h" +#include "kis_grid_manager.h" +#include "kis_perspective_grid_manager.h" + +#include "kis_custom_palette.h" +#include "wdgpalettechooser.h" + +#include <fixx11h.h> + +// Time in ms that must pass after a tablet event before a mouse event is allowed to +// change the input device to the mouse. This is needed because mouse events are always +// sent to a receiver if it does not accept the tablet event. +#define MOUSE_CHANGE_EVENT_DELAY 100 + +KisView::KisView(KisDoc *doc, KisUndoAdapter *adapter, TQWidget *tqparent, const char *name) + : super(doc, tqparent, name) + , KXMLGUIBuilder( shell() ) + , m_panning( false ) + , m_oldTool( 0 ) + , m_doc( doc ) + , m_canvas( 0 ) + , m_partHandler( 0 ) + , m_gridManager( 0 ) + , m_perspectiveGridManager( 0 ) + , m_selectionManager( 0 ) + , m_filterManager( 0 ) + , m_paletteManager( 0 ) + , m_toolManager( 0 ) + , m_actLayerVis( false ) + , m_hRuler( 0 ) + , m_vRuler( 0 ) + , m_imgFlatten( 0 ) + , m_imgMergeLayer( 0 ) + , m_imgRename( 0 ) + , m_imgResizeToLayer( 0 ) + , m_imgScan( 0 ) + , m_actionPartLayer( 0 ) + , m_layerAdd( 0 ) + , m_layerBottom( 0 ) + , m_layerDup( 0 ) + , m_layerHide( 0 ) + , m_layerLower( 0 ) + , m_layerProperties( 0 ) + , m_layerRaise( 0 ) + , m_layerRm( 0 ) + , m_layerSaveAs( 0 ) + , m_layerTop( 0 ) + , m_zoomIn( 0 ) + , m_zoomOut( 0 ) + , m_actualPixels( 0 ) + , m_actualSize( 0 ) + , m_fitToCanvas( 0 ) + , m_fullScreen( 0 ) + , m_imgProperties( 0 ) + , m_RulerAction( 0 ) + , m_guideAction( 0 ) + , m_dcop( 0 ) + , m_hScroll( 0 ) + , m_vScroll( 0 ) + , m_scrollX( 0 ) + , m_scrollY( 0 ) + , m_canvasXOffset( 0) + , m_canvasYOffset( 0) + , m_paintViewEnabled( false ) + , m_guiActivateEventReceived( false ) + , m_showEventReceived( false ) + , m_imageLoaded( false ) +// , m_currentGuide( 0 ) + , m_adapter( adapter ) + , m_statusBarZoomLabel( 0 ) + , m_statusBarSelectionLabel( 0 ) + , m_statusBarProfileLabel( 0 ) + , m_progress( 0 ) + , m_layerBox( 0 ) + , m_toolBox( 0 ) + , m_brush( 0 ) + , m_pattern( 0 ) + , m_gradient( 0 ) + , m_toolIsPainting( false ) + , m_monitorProfile( 0 ) + , m_HDRExposure( 0 ) +{ + + Q_ASSERT(doc); + Q_ASSERT(adapter); + Q_ASSERT(tqparent); + + KisConfig cfg; + + m_currentColorChooserDisplay = KisID("BLA"); + setFocusPolicy( TQ_StrongFocus ); + + // Must come before input devices are referenced as this detects them. +#ifdef Q_WS_X11 + KisCanvasWidget::initX11Support(); +#endif + // Install event filter before we create any child widgets so they can see + // the tablet events. + tqApp->installEventFilter(this); + + m_tabletEventTimer.start(); + m_inputDevice = KisInputDevice::mouse(); + + connect(&m_initialZoomTimer, TQT_SIGNAL(timeout()), TQT_SLOT(slotInitialZoomTimeout())); + + m_paletteManager = new KoPaletteManager(this, actionCollection(), "Chalk palette manager"); + if (cfg.fixDockerWidth()) m_paletteManager->setFixedWidth( 360 ); + + m_paletteManager->createPalette( chalk::CONTROL_PALETTE, i18n("Control box")); + m_paletteManager->createPalette( chalk::COLORBOX, i18n("Colors")); + m_paletteManager->createPalette( chalk::LAYERBOX, i18n("Layers")); + + m_selectionManager = new KisSelectionManager(this, doc); + m_filterManager = new KisFilterManager(this, doc); + m_toolManager = new KisToolManager(canvasSubject(), getCanvasController()); + m_gridManager = new KisGridManager(this); + m_perspectiveGridManager = new KisPerspectiveGridManager(this); + + // This needs to be set before the dockers are created. + m_image = m_doc->currentImage(); + KisColorSpace * cs = KisMetaRegistry::instance()->csRegistry()->getRGB8(); + m_fg = KisColor(TQt::black, cs); + m_bg = KisColor(TQt::white, cs); + + createDockers(); + + setInstance(KisFactory::instance(), false); + setClientBuilder( this ); + + if (!doc->isReadWrite()) + setXMLFile("chalk_readonly.rc"); + else + setXMLFile("chalk.rc"); + + KStdAction::keyBindings( mainWindow()->guiFactory(), TQT_SLOT( configureShortcuts() ), actionCollection() ); + + createLayerBox(); + + setupCanvas(); + m_canvas->hide(); + setupRulers(); + setupScrollBars(); + setupStatusBar(); + + setupActions(); + dcopObject(); + + + connect(TQT_TQOBJECT(this), TQT_SIGNAL(autoScroll(const TQPoint &)), TQT_SLOT(slotAutoScroll(const TQPoint &))); + + setMouseTracking(true); + + resetMonitorProfile(); + + layersUpdated(); + + m_brushesAndStuffToolBar = new KisControlFrame(mainWindow(), this); + + // Load all plugins + KTrader::OfferList offers = KTrader::self()->query(TQString::tqfromLatin1("Chalk/ViewPlugin"), + TQString::tqfromLatin1("(Type == 'Service') and " + "([X-Chalk-Version] == 2)")); + KTrader::OfferList::ConstIterator iter; + for(iter = offers.begin(); iter != offers.end(); ++iter) + { + KService::Ptr service = *iter; + int errCode = 0; + KParts::Plugin* plugin = + KParts::ComponentFactory::createInstanceFromService<KParts::Plugin> ( service, TQT_TQOBJECT(this), 0, TQStringList(), &errCode); + if ( plugin ) { + kdDebug(41006) << "found plugin " << service->property("Name").toString() << "\n"; + insertChildClient(plugin); + } + else { + kdDebug(41006) << "found plugin " << service->property("Name").toString() << ", " << errCode << "\n"; + if( errCode == KParts::ComponentFactory::ErrNoLibrary) + { + kdWarning(41006) << " Error loading plugin was : ErrNoLibrary " << KLibLoader::self()->lastErrorMessage() << endl; + } + } + } + + if(!doc->isLoading()) + { + slotLoadingFinished(); + } else { + connect(doc, TQT_SIGNAL(loadingFinished()), TQT_TQOBJECT(this), TQT_SLOT(slotLoadingFinished())); + } + + setFocus(); +} + +KisView::~KisView() +{ + KisConfig cfg; + cfg.setShowRulers( m_RulerAction->isChecked() ); + + delete m_dcop; + delete m_paletteManager; + delete m_selectionManager; + delete m_filterManager; + delete m_toolManager; + +} + + +static TQt::Dock stringToDock( const TQString& attrPosition ) +{ + KToolBar::Dock dock = KToolBar::DockTop; + if ( !attrPosition.isEmpty() ) { + if ( attrPosition == "top" ) + dock = TQt::DockTop; + else if ( attrPosition == "left" ) + dock = TQt::DockLeft; + else if ( attrPosition == "right" ) + dock = TQt::DockRight; + else if ( attrPosition == "bottom" ) + dock = TQt::DockBottom; + else if ( attrPosition == "floating" ) + dock = TQt::DockTornOff; + else if ( attrPosition == "flat" ) + dock = TQt::DockMinimized; + } + return dock; +} + +TQWidget * KisView::createContainer( TQWidget *tqparent, int index, const TQDomElement &element, int &id ) +{ + if( element.attribute( "name" ) == "ToolBox" ) + { + m_toolBox = new KoToolBox(mainWindow(), "ToolBox", KisFactory::instance(), NUMBER_OF_TOOLTYPES); + m_toolBox->setLabel(i18n("Chalk")); + m_toolManager->setUp(m_toolBox, m_paletteManager, actionCollection()); + + Dock dock = stringToDock( element.attribute( "position" ).lower() ); + + mainWindow()->addDockWindow( m_toolBox, dock, false); + mainWindow()->moveDockWindow( m_toolBox, dock, false, 0, 0 ); + } + + return KXMLGUIBuilder::createContainer( tqparent, index, element, id ); + +} + +void KisView::removeContainer( TQWidget *container, TQWidget *tqparent, TQDomElement &element, int id ) +{ + Q_ASSERT(container); + + if( shell() && container == m_toolBox ) + { + delete m_toolBox; + m_toolManager->youAintGotNoToolBox(); + } + else { + KXMLGUIBuilder::removeContainer( container, tqparent, element, id ); + } +} + +KoPaletteManager * KisView::paletteManager() +{ + if (!m_paletteManager) { + m_paletteManager = new KoPaletteManager(this, actionCollection(), "Chalk palette manager"); + Q_CHECK_PTR(m_paletteManager); + } + return m_paletteManager; +} + +void KisView::createLayerBox() +{ + m_layerBox = new KisLayerBox(this); + m_layerBox->setCaption(i18n("Layers")); + + connect(m_layerBox, TQT_SIGNAL(sigRequestLayer(KisGroupLayerSP, KisLayerSP)), + TQT_TQOBJECT(this), TQT_SLOT(addLayer(KisGroupLayerSP, KisLayerSP))); + connect(m_layerBox, TQT_SIGNAL(sigRequestGroupLayer(KisGroupLayerSP, KisLayerSP)), + TQT_TQOBJECT(this), TQT_SLOT(addGroupLayer(KisGroupLayerSP, KisLayerSP))); + connect(m_layerBox, TQT_SIGNAL(sigRequestAdjustmentLayer(KisGroupLayerSP, KisLayerSP)), + TQT_TQOBJECT(this), TQT_SLOT(addAdjustmentLayer(KisGroupLayerSP, KisLayerSP))); + connect(m_layerBox, TQT_SIGNAL(sigRequestPartLayer(KisGroupLayerSP, KisLayerSP, const KoDocumentEntry&)), + TQT_TQOBJECT(this), TQT_SLOT(addPartLayer(KisGroupLayerSP, KisLayerSP, const KoDocumentEntry&))); + connect(m_layerBox, TQT_SIGNAL(sigRequestLayerProperties(KisLayerSP)), + TQT_TQOBJECT(this), TQT_SLOT(showLayerProperties(KisLayerSP))); + connect(m_layerBox, TQT_SIGNAL(sigOpacityChanged(int, bool)), TQT_TQOBJECT(this), TQT_SLOT(layerOpacity(int, bool))); + connect(m_layerBox, TQT_SIGNAL(sigOpacityFinishedChanging(int, int)), + TQT_TQOBJECT(this), TQT_SLOT(layerOpacityFinishedChanging(int, int))); + connect(m_layerBox, TQT_SIGNAL(sigItemComposite(const KisCompositeOp&)), TQT_TQOBJECT(this), TQT_SLOT(layerCompositeOp(const KisCompositeOp&))); + + paletteManager()->addWidget(m_layerBox, "layerbox", chalk::LAYERBOX, 0); + +} + +DCOPObject* KisView::dcopObject() +{ + if (!m_dcop) { + m_dcop = new KisViewIface(this); + Q_CHECK_PTR(m_dcop); + } + return m_dcop; +} + +void KisView::setupScrollBars() +{ + m_scrollX = 0; + m_scrollY = 0; + m_vScroll = new TQScrollBar(Qt::Vertical, this); + Q_CHECK_PTR(m_vScroll); + + m_hScroll = new TQScrollBar(Qt::Horizontal, this); + Q_CHECK_PTR(m_hScroll); + + m_vScroll->setGeometry(width() - 16, 20, 16, height() - 36); + m_hScroll->setGeometry(20, height() - 16, width() - 36, 16); + m_hScroll->setValue(0); + m_vScroll->setValue(0); + TQObject::connect(m_vScroll, TQT_SIGNAL(valueChanged(int)), TQT_TQOBJECT(this), TQT_SLOT(scrollV(int))); + TQObject::connect(m_hScroll, TQT_SIGNAL(valueChanged(int)), TQT_TQOBJECT(this), TQT_SLOT(scrollH(int))); +} + +void KisView::setupRulers() +{ + m_hRuler = new KisRuler(Qt::Horizontal, this); + Q_CHECK_PTR(m_hRuler); + + m_vRuler = new KisRuler(Qt::Vertical, this); + Q_CHECK_PTR(m_vRuler); + + m_hRuler->setGeometry(20, 0, width() - 20, 20); + m_vRuler->setGeometry(0, 20, 20, height() - 20); + + if (statusBar()) { + m_hRuler->installEventFilter(this); + m_vRuler->installEventFilter(this); + } +} + +#define EPSILON 1e-6 + +void KisView::updateStatusBarZoomLabel () +{ + if (zoom() < 1 - EPSILON) { + m_statusBarZoomLabel->setText(i18n("Zoom %1%").tqarg(zoom() * 100, 0, 'g', 4)); + } else { + m_statusBarZoomLabel->setText(i18n("Zoom %1%").tqarg(zoom() * 100, 0, 'f', 0)); + } + m_statusBarZoomLabel->setMaximumWidth(m_statusBarZoomLabel->fontMetrics().width(i18n("Zoom %1%").tqarg("0.8888 "))); +} + +void KisView::updateStatusBarSelectionLabel() +{ + if (m_statusBarSelectionLabel == 0) { + return; + } + + KisImageSP img = currentImg(); + if (img) { + KisPaintDeviceSP dev = img->activeDevice(); + if (dev) { + if (dev->hasSelection()) { + TQRect r = dev->selection()->selectedExactRect(); + m_statusBarSelectionLabel->setText( i18n("Selection Active: x = %1 y = %2 width = %3 height = %4").tqarg(r.x()).tqarg(r.y()).tqarg( r.width()).tqarg( r.height())); + return; + } + } + } + + m_statusBarSelectionLabel->setText(i18n("No Selection")); +} + +void KisView::updateStatusBarProfileLabel() +{ + if (m_statusBarProfileLabel == 0) { + return; + } + + KisImageSP img = currentImg(); + if (!img) return; + + if (img->getProfile() == 0) { + m_statusBarProfileLabel->setText(i18n("No profile")); + } + else { + m_statusBarProfileLabel->setText(img->colorSpace()->id().name() + " " + img->getProfile()->productName()); + } +} + + +KisProfile * KisView::monitorProfile() +{ + if (m_monitorProfile == 0) { + resetMonitorProfile(); + } + return m_monitorProfile; +} + + +void KisView::resetMonitorProfile() +{ + m_monitorProfile = KisProfile::getScreenProfile(); + + if (m_monitorProfile == 0) { + KisConfig cfg; + TQString monitorProfileName = cfg.monitorProfile(); + m_monitorProfile = KisMetaRegistry::instance()->csRegistry()->getProfileByName(monitorProfileName); + } + +} + +void KisView::setupStatusBar() +{ + KStatusBar *sb = statusBar(); + + if (sb) { + m_statusBarZoomLabel = new TQLabel(sb); + addStatusBarItem(m_statusBarZoomLabel,1); + updateStatusBarZoomLabel(); + + m_statusBarSelectionLabel = new KSqueezedTextLabel(sb); + addStatusBarItem(m_statusBarSelectionLabel,2); + updateStatusBarSelectionLabel(); + + m_statusBarProfileLabel = new KSqueezedTextLabel(sb); + addStatusBarItem(m_statusBarProfileLabel,3); + updateStatusBarProfileLabel(); + + //int height = m_statusBarProfileLabel->height(); + + m_progress = new KisLabelProgress(this); + m_progress->setMaximumWidth(225); + m_progress->setMinimumWidth(225); + m_progress->setMaximumHeight(fontMetrics().height() ); + addStatusBarItem(m_progress, 2, true); + + m_progress->hide(); + } +} + +void KisView::setupActions() +{ + KisConfig cfg; + + m_selectionManager->setup(actionCollection()); + m_filterManager->setup(actionCollection()); + m_gridManager->setup(actionCollection()); + m_perspectiveGridManager->setup(actionCollection()); + + + m_fullScreen = KStdAction::fullScreen( NULL, NULL, actionCollection(), this ); + connect( m_fullScreen, TQT_SIGNAL( toggled( bool )), TQT_TQOBJECT(this), TQT_SLOT( slotUpdateFullScreen( bool ))); + + m_imgProperties = new KAction(i18n("Image Properties"), 0, TQT_TQOBJECT(this), TQT_SLOT(slotImageProperties()), actionCollection(), "img_properties"); + m_imgScan = 0; // How the hell do I get a KAction to the scan plug-in?!? + m_imgResizeToLayer = new KAction(i18n("Resize Image to Size of Current Layer"), 0, TQT_TQOBJECT(this), TQT_SLOT(imgResizeToActiveLayer()), actionCollection(), "resizeimgtolayer"); + + // view actions + m_zoomIn = KStdAction::zoomIn(TQT_TQOBJECT(this), TQT_SLOT(slotZoomIn()), actionCollection(), "zoom_in"); + m_zoomOut = KStdAction::zoomOut(TQT_TQOBJECT(this), TQT_SLOT(slotZoomOut()), actionCollection(), "zoom_out"); + m_actualPixels = new KAction(i18n("Actual Pixels"), "Ctrl+0", TQT_TQOBJECT(this), TQT_SLOT(slotActualPixels()), actionCollection(), "actual_pixels"); + m_actualSize = KStdAction::actualSize(TQT_TQOBJECT(this), TQT_SLOT(slotActualSize()), actionCollection(), "actual_size"); + m_actualSize->setEnabled(false); + m_fitToCanvas = KStdAction::fitToPage(TQT_TQOBJECT(this), TQT_SLOT(slotFitToCanvas()), actionCollection(), "fit_to_canvas"); + + // layer actions + m_layerAdd = new KAction(i18n("&Add..."), "Ctrl+Shift+N", TQT_TQOBJECT(this), TQT_SLOT(layerAdd()), actionCollection(), "insert_layer"); + + m_actionPartLayer = new KoPartSelectAction( i18n( "&Object Layer" ), "frame_query", + TQT_TQOBJECT(this), TQT_SLOT( addPartLayer() ), + actionCollection(), "insert_part_layer" ); + + + m_actionAdjustmentLayer = new KAction( i18n( "&Adjustment Layer" ), 0, + TQT_TQOBJECT(this), TQT_SLOT( addAdjustmentLayer() ), + actionCollection(), "insert_adjustment_layer" ); + + + m_layerRm = new KAction(i18n("&Remove"), 0, TQT_TQOBJECT(this), TQT_SLOT(layerRemove()), actionCollection(), "remove_layer"); + m_layerDup = new KAction(i18n("Duplicate"), 0, TQT_TQOBJECT(this), TQT_SLOT(layerDuplicate()), actionCollection(), "duplicate_layer"); + m_layerHide = new KToggleAction(i18n("&Hide"), 0, TQT_TQOBJECT(this), TQT_SLOT(layerToggleVisible()), actionCollection(), "hide_layer"); + m_layerHide->setCheckedState(KGuiItem(i18n("&Show"))); + m_layerHide->setChecked(false); + + m_layerRaise = new KAction(i18n("Raise"), "raise", "Ctrl+]", TQT_TQOBJECT(this), TQT_SLOT(layerRaise()), actionCollection(), "raiselayer"); + m_layerLower = new KAction(i18n("Lower"), "lower", "Ctrl+[", TQT_TQOBJECT(this), TQT_SLOT(layerLower()), actionCollection(), "lowerlayer"); + m_layerTop = new KAction(i18n("To Top"), "bring_forward", "Ctrl+Shift+]", TQT_TQOBJECT(this), TQT_SLOT(layerFront()), actionCollection(), "toplayer"); + m_layerBottom = new KAction(i18n("To Bottom"), "send_backward", "Ctrl+Shift+[", TQT_TQOBJECT(this), TQT_SLOT(layerBack()), actionCollection(), "bottomlayer"); + m_layerProperties = new KAction(i18n("Properties"), 0, TQT_TQOBJECT(this), TQT_SLOT(layerProperties()), actionCollection(), "layer_properties"); + (void)new KAction(i18n("I&nsert Image as Layer..."), 0, TQT_TQOBJECT(this), TQT_SLOT(slotInsertImageAsLayer()), actionCollection(), "insert_image_as_layer"); + m_layerSaveAs = new KAction(i18n("Save Layer as Image..."), "filesave", TQT_TQOBJECT(this), TQT_SLOT(saveLayerAsImage()), actionCollection(), "save_layer_as_image"); + (void)new KAction(i18n("Flip on &X Axis"), "view_left_right", 0, TQT_TQOBJECT(this), TQT_SLOT(mirrorLayerX()), actionCollection(), "mirrorLayerX"); + (void)new KAction(i18n("Flip on &Y Axis"), "view_top_bottom", 0, TQT_TQOBJECT(this), TQT_SLOT(mirrorLayerY()), actionCollection(), "mirrorLayerY"); + + m_createMask = new KAction(i18n("Create Mask"), 0, TQT_TQOBJECT(this), + TQT_SLOT(slotCreateMask()), actionCollection(), "create_tqmask"); + m_tqmaskFromSelection = new KAction(i18n("Mask From Selection"), 0, TQT_TQOBJECT(this), + TQT_SLOT(slotMaskFromSelection()), actionCollection(), + "tqmask_fromsel"); + m_tqmaskToSelection = new KAction(i18n("Mask to Selection"), 0, TQT_TQOBJECT(this), + TQT_SLOT(slotMaskToSelection()), actionCollection(), "tqmask_tosel"); + m_applyMask = new KAction(i18n("Apply Mask"), 0, TQT_TQOBJECT(this), TQT_SLOT(slotApplyMask()), + actionCollection(), "apply_tqmask"); + m_removeMask = new KAction(i18n("Remove Mask"), 0, TQT_TQOBJECT(this), + TQT_SLOT(slotRemoveMask()), actionCollection(), "remove_tqmask"); + m_showMask = new KToggleAction(i18n( "Show Mask" ), 0, TQT_TQOBJECT(this), + TQT_SLOT(slotShowMask()), actionCollection(), "show_tqmask"); + m_editMask = new KToggleAction(i18n( "Edit Mask" ), 0, TQT_TQOBJECT(this), + TQT_SLOT(slotEditMask()), actionCollection(), "edit_tqmask"); + + // image actions + m_imgFlatten = new KAction(i18n("&Flatten Image"), "Ctrl+Shift+E", TQT_TQOBJECT(this), TQT_SLOT(flattenImage()), actionCollection(), "flatten_image"); + m_imgMergeLayer = new KAction(i18n("&Merge with Layer Below"), "Ctrl+E", TQT_TQOBJECT(this), TQT_SLOT(mergeLayer()), actionCollection(), "merge_layer"); + + // setting actions + KStdAction::preferences(TQT_TQOBJECT(this), TQT_SLOT(preferences()), actionCollection(), "preferences"); + + m_RulerAction = new KToggleAction( i18n( "Show Rulers" ), "Ctrl+R", TQT_TQOBJECT(this), TQT_SLOT( showRuler() ), actionCollection(), "view_ruler" ); + m_RulerAction->setChecked(cfg.showRulers()); + m_RulerAction->setCheckedState(i18n("Hide Rulers")); + m_RulerAction->setWhatsThis( i18n("The rulers show the horizontal and vertical positions of the mouse on the image " + "and can be used to position your mouse at the right place on the canvas. <p>Uncheck this to disable " + "the rulers from being displayed." ) ); + + //m_guideAction = new KToggleAction( i18n( "Guide Lines" ), 0, TQT_TQOBJECT(this), TQT_SLOT( viewGuideLines() ), actionCollection(), "view_guidelines" ); + + // Add new palette + new KAction(i18n("Add New Palette..."), 0, TQT_TQOBJECT(this), TQT_SLOT(slotAddPalette()), + actionCollection(), "add_palette"); + new KAction(i18n("Edit Palette..."), 0, TQT_TQOBJECT(this), TQT_SLOT(slotEditPalette()), + actionCollection(), "edit_palette"); + + // XXX: This triggers a tqrepaint of the image, but way too early + //showRuler(); + +} + +void KisView::resizeEvent(TQResizeEvent *) +{ + if (!m_paintViewEnabled) { + startInitialZoomTimerIfReady(); + } + + KisImageSP img = currentImg(); + TQ_INT32 scrollBarExtent = tqstyle().tqpixelMetric(TQStyle::PM_ScrollBarExtent); + TQ_INT32 drawH; + TQ_INT32 drawW; + TQ_INT32 docW; + TQ_INT32 docH; + +// if (img) { +// KisGuideMgr *mgr = img->guides(); +// mgr->resize(size()); +// } + + docW = static_cast<TQ_INT32>(ceil(docWidth() * zoom())); + docH = static_cast<TQ_INT32>(ceil(docHeight() * zoom())); + + m_rulerThickness = m_RulerAction->isChecked() ? RULER_THICKNESS : 0; + drawH = height() - m_rulerThickness; + drawW = width() - m_rulerThickness; + + if (drawH < docH) { + // Will need vert scrollbar + drawW -= scrollBarExtent; + if (drawW < docW) + // Will need horiz scrollbar + drawH -= scrollBarExtent; + } else if (drawW < docW) { + // Will need horiz scrollbar + drawH -= scrollBarExtent; + if (drawH < docH) + // Will need vert scrollbar + drawW -= scrollBarExtent; + } + + m_vScroll->setEnabled(docH > drawH); + m_hScroll->setEnabled(docW > drawW); + + if (docH <= drawH && docW <= drawW) { + // we need no scrollbars + m_vScroll->hide(); + m_hScroll->hide(); + m_vScroll->setValue(0); + m_hScroll->setValue(0); + m_vScrollBarExtent = 0; + m_hScrollBarExtent = 0; + } else if (docH <= drawH) { + // we need a horizontal scrollbar only + m_vScroll->hide(); + m_vScroll->setValue(0); + m_hScroll->setRange(0, docW - drawW); + m_hScroll->setGeometry(m_rulerThickness, + height() - scrollBarExtent, + width() - m_rulerThickness, + scrollBarExtent); + m_hScroll->show(); + m_hScrollBarExtent = scrollBarExtent; + m_hScrollBarExtent = scrollBarExtent; + } else if(docW <= drawW) { + // we need a vertical scrollbar only + m_hScroll->hide(); + m_hScroll->setValue(0); + m_vScroll->setRange(0, docH - drawH); + m_vScroll->setGeometry(width() - scrollBarExtent, m_rulerThickness, scrollBarExtent, height() - m_rulerThickness); + m_vScroll->show(); + m_vScrollBarExtent = scrollBarExtent; + } else { + // we need both scrollbars + m_vScroll->setRange(0, docH - drawH); + m_vScroll->setGeometry(width() - scrollBarExtent, + m_rulerThickness, + scrollBarExtent, + height() -2* m_rulerThickness); + m_hScroll->setRange(0, docW - drawW); + m_hScroll->setGeometry(m_rulerThickness, + height() - scrollBarExtent, + width() - 2*m_rulerThickness, + scrollBarExtent); + m_vScroll->show(); + m_hScroll->show(); + m_vScrollBarExtent = scrollBarExtent; + m_hScrollBarExtent = scrollBarExtent; + } + + TQ_INT32 oldCanvasXOffset = m_canvasXOffset; + TQ_INT32 oldCanvasYOffset = m_canvasYOffset; + + if (docW < drawW) { + m_canvasXOffset = (drawW - docW) / 2; + } else { + m_canvasXOffset = 0; + } + + if (docH < drawH) { + m_canvasYOffset = (drawH - docH) / 2; + } else { + m_canvasYOffset = 0; + } + + //Check if rulers are visible + if( m_RulerAction->isChecked() ) + m_canvas->setGeometry(m_rulerThickness, m_rulerThickness, drawW, drawH); + else + m_canvas->setGeometry(0, 0, drawW, drawH); + m_canvas->show(); + + if (!m_canvas->isOpenGLCanvas()) { + + if (m_canvasPixmap.size() != TQSize(drawW, drawH)) { + + TQ_INT32 oldCanvasWidth = m_canvasPixmap.width(); + TQ_INT32 oldCanvasHeight = m_canvasPixmap.height(); + + TQ_INT32 newCanvasWidth = drawW; + TQ_INT32 newCanvasHeight = drawH; + + TQRegion exposedRegion = TQRect(0, 0, newCanvasWidth, newCanvasHeight); + + // Increase size first so that we can copy the old image area to the new one. + m_canvasPixmap.resize(TQMAX(oldCanvasWidth, newCanvasWidth), TQMAX(oldCanvasHeight, newCanvasHeight)); + + if (!m_canvasPixmap.isNull()) { + + if (oldCanvasXOffset != m_canvasXOffset || oldCanvasYOffset != m_canvasYOffset) { + + TQ_INT32 srcX; + TQ_INT32 srcY; + TQ_INT32 srcWidth; + TQ_INT32 srcHeight; + TQ_INT32 dstX; + TQ_INT32 dstY; + + if (oldCanvasXOffset <= m_canvasXOffset) { + // Move to the right + srcX = 0; + dstX = m_canvasXOffset - oldCanvasXOffset; + srcWidth = oldCanvasWidth; + } else { + // Move to the left + srcX = oldCanvasXOffset - m_canvasXOffset; + dstX = 0; + srcWidth = newCanvasWidth; + } + + if (oldCanvasYOffset <= m_canvasYOffset) { + // Move down + srcY = 0; + dstY = m_canvasYOffset - oldCanvasYOffset; + srcHeight = oldCanvasHeight; + } else { + // Move up + srcY = oldCanvasYOffset - m_canvasYOffset; + dstY = 0; + srcHeight = newCanvasHeight; + } + + bitBlt(&m_canvasPixmap, dstX, dstY, &m_canvasPixmap, srcX, srcY, srcWidth, srcHeight); + exposedRegion -= TQRegion(TQRect(dstX, dstY, srcWidth, srcHeight)); + } else { + exposedRegion -= TQRegion(TQRect(0, 0, oldCanvasWidth, oldCanvasHeight)); + } + } + + m_canvasPixmap.resize(newCanvasWidth, newCanvasHeight); + + if (!m_canvasPixmap.isNull() && !exposedRegion.isEmpty()) { + + TQMemArray<TQRect> rects = exposedRegion.tqrects(); + + for (unsigned int i = 0; i < rects.count(); i++) { + TQRect r = rects[i]; + updateTQPaintDeviceCanvas(viewToWindow(r)); + } + } + } + } + + int fontheight = TQFontMetrics(KGlobalSettings::generalFont()).height() * 3; + m_vScroll->setPageStep(drawH); + m_vScroll->setLineStep(fontheight); + m_hScroll->setPageStep(drawW); + m_hScroll->setLineStep(fontheight); + + m_hRuler->setGeometry(m_rulerThickness + m_canvasXOffset, 0, TQMIN(docW, drawW), m_rulerThickness); + m_vRuler->setGeometry(0, m_rulerThickness + m_canvasYOffset, m_rulerThickness, TQMIN(docH, drawH)); + + if (m_vScroll->isVisible()) + m_vRuler->updateVisibleArea(0, m_vScroll->value()); + else + m_vRuler->updateVisibleArea(0, 0); + + if (m_hScroll->isVisible()) + m_hRuler->updateVisibleArea(m_hScroll->value(), 0); + else + m_hRuler->updateVisibleArea(0, 0); + + if( m_RulerAction->isChecked() ) + { + m_hRuler->show(); + m_vRuler->show(); + } + else { + m_hRuler->hide(); + m_vRuler->hide(); + } + + emit viewTransformationsChanged(); +} + +void KisView::styleChange(TQStyle& oldStyle) +{ + Q_UNUSED(oldStyle); + m_canvas->updateGeometry(); + refreshKisCanvas(); +} + +void KisView::paletteChange(const TQPalette& oldPalette) +{ + Q_UNUSED(oldPalette); + refreshKisCanvas(); +} + +void KisView::showEvent(TQShowEvent *) +{ + if (!m_showEventReceived) { + m_showEventReceived = true; + startInitialZoomTimerIfReady(); + } +} + +void KisView::updateReadWrite(bool readwrite) +{ + layerUpdateGUI(readwrite); +} + +TQ_INT32 KisView::horzValue() const +{ + return m_hScroll->value() - m_canvasXOffset; +} + +TQ_INT32 KisView::vertValue() const +{ + return m_vScroll->value() - m_canvasYOffset; +} + +void KisView::updateTQPaintDeviceCanvas(const TQRect& imageRect) +{ + TQRect vr = windowToView(imageRect); + vr &= TQRect(0, 0, m_canvas->width(), m_canvas->height()); + + if (!vr.isEmpty()) { + + TQPainter gc; + + if (gc.begin(&m_canvasPixmap)) { + + KisImageSP img = currentImg(); + + if (img && m_paintViewEnabled) { + + TQRect wr = viewToWindow(vr); + + if (wr.left() < 0 || wr.right() >= img->width() || wr.top() < 0 || wr.bottom() >= img->height()) { + // Erase areas outside document + TQRegion rg(vr); + rg -= TQRegion(windowToView(TQRect(0, 0, img->width(), img->height()))); + + TQMemArray<TQRect> rects = rg.tqrects(); + + for (unsigned int i = 0; i < rects.count(); i++) { + TQRect er = rects[i]; + gc.fillRect(er, tqcolorGroup().mid()); + } + wr &= TQRect(0, 0, img->width(), img->height()); + } + + if (!wr.isEmpty()) { + + KisImage::PaintFlags paintFlags = (KisImage::PaintFlags)KisImage::PAINT_BACKGROUND; + + if (m_actLayerVis) { + paintFlags = (KisImage::PaintFlags)(paintFlags|KisImage::PAINT_MASKINACTIVELAYERS); + } + + if (m_selectionManager->displaySelection()) + { + paintFlags = (KisImage::PaintFlags)(paintFlags|KisImage::PAINT_SELECTION); + } + + if (zoom() > 1.0 - EPSILON) { + + gc.setWorldXForm(true); + gc.translate(-horzValue(), -vertValue()); + gc.scale(zoomFactor(), zoomFactor()); + + m_image->renderToPainter(wr.left(), wr.top(), + wr.right(), wr.bottom(), gc, monitorProfile(), + paintFlags, HDRExposure()); + } else { + + TQRect canvasRect = windowToView(wr); + TQRect scaledImageRect = canvasRect; + scaledImageRect.moveBy(horzValue(), vertValue()); + + TQSize scaledImageSize(static_cast<TQ_INT32>(ceil(docWidth() * zoom())), + static_cast<TQ_INT32>(ceil(docHeight() * zoom()))); + + TQImage image = m_image->convertToTQImage(scaledImageRect, scaledImageSize, + monitorProfile(), paintFlags, HDRExposure()); + + gc.drawImage(canvasRect.topLeft(), image, image.rect()); + + // Set up for the grid drawer. + gc.setWorldXForm(true); + gc.translate(-horzValue(), -vertValue()); + gc.scale(zoomFactor(), zoomFactor()); + } + + m_gridManager->drawGrid( wr, &gc ); + m_perspectiveGridManager->drawGrid( wr, &gc ); + } +// paintGuides(); + } else { + gc.fillRect(vr, tqcolorGroup().mid()); + } + } + } +} + +void KisView::paintTQPaintDeviceView(const TQRegion& canvasRegion) +{ + Q_ASSERT(m_canvas->TQPaintDeviceWidget() != 0); + + if (m_canvas->TQPaintDeviceWidget() != 0 && !m_canvasPixmap.isNull()) { + TQMemArray<TQRect> rects = canvasRegion.tqrects(); + + for (unsigned int i = 0; i < rects.count(); i++) { + TQRect r = rects[i]; + + bitBlt(m_canvas->TQPaintDeviceWidget(), r.x(), r.y(), &m_canvasPixmap, + r.x(), r.y(), r.width(), r.height()); + } + + paintToolOverlay(canvasRegion); + } +} + +void KisView::updateOpenGLCanvas(const TQRect& imageRect) +{ +#ifdef HAVE_GL + KisImageSP img = currentImg(); + + if (img && m_paintViewEnabled) { + Q_ASSERT(m_OpenGLImageContext != 0); + + if (m_OpenGLImageContext != 0) { + m_OpenGLImageContext->update(imageRect); + } + } +#else + Q_UNUSED(imageRect); +#endif +} + +void KisView::paintOpenGLView(const TQRect& canvasRect) +{ +#ifdef HAVE_GL + if (!m_canvas->isUpdatesEnabled()) { + return; + } + + m_canvas->OpenGLWidget()->makeCurrent(); + + glDrawBuffer(GL_BACK); + + TQColor widgetBackgroundColor = tqcolorGroup().mid(); + + glClearColor(widgetBackgroundColor.red() / 255.0, widgetBackgroundColor.green() / 255.0, widgetBackgroundColor.blue() / 255.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + KisImageSP img = currentImg(); + + if (img && m_paintViewEnabled) { + + TQRect vr = canvasRect; + vr &= TQRect(0, 0, m_canvas->width(), m_canvas->height()); + + if (!vr.isNull()) { + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glViewport(0, 0, m_canvas->width(), m_canvas->height()); + glOrtho(0, m_canvas->width(), m_canvas->height(), 0, -1, 1); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glBindTexture(GL_TEXTURE_2D, m_OpenGLImageContext->backgroundTexture()); + + glTranslatef(m_canvasXOffset, m_canvasYOffset, 0.0); + + glEnable(GL_TEXTURE_2D); + glBegin(GL_QUADS); + + glTexCoord2f(0.0, 0.0); + glVertex2f(0.0, 0.0); + + glTexCoord2f((img->width() * zoom()) / KisOpenGLImageContext::BACKGROUND_TEXTURE_WIDTH, 0.0); + glVertex2f(img->width() * zoom(), 0.0); + + glTexCoord2f((img->width() * zoom()) / KisOpenGLImageContext::BACKGROUND_TEXTURE_WIDTH, + (img->height() * zoom()) / KisOpenGLImageContext::BACKGROUND_TEXTURE_HEIGHT); + glVertex2f(img->width() * zoom(), img->height() * zoom()); + + glTexCoord2f(0.0, (img->height() * zoom()) / KisOpenGLImageContext::BACKGROUND_TEXTURE_HEIGHT); + glVertex2f(0.0, img->height() * zoom()); + + glEnd(); + + glTranslatef(-m_canvasXOffset, -m_canvasYOffset, 0.0); + + glTranslatef(-horzValue(), -vertValue(), 0.0); + glScalef(zoomFactor(), zoomFactor(), 1.0); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + TQRect wr = viewToWindow(TQRect(0, 0, m_canvas->width(), m_canvas->height())); + wr &= TQRect(0, 0, img->width(), img->height()); + + m_OpenGLImageContext->setHDRExposure(HDRExposure()); + + m_canvas->OpenGLWidget()->makeCurrent(); + + for (int x = (wr.left() / m_OpenGLImageContext->imageTextureTileWidth()) * m_OpenGLImageContext->imageTextureTileWidth(); + x <= wr.right(); + x += m_OpenGLImageContext->imageTextureTileWidth()) { + for (int y = (wr.top() / m_OpenGLImageContext->imageTextureTileHeight()) * m_OpenGLImageContext->imageTextureTileHeight(); + y <= wr.bottom(); + y += m_OpenGLImageContext->imageTextureTileHeight()) { + + glBindTexture(GL_TEXTURE_2D, m_OpenGLImageContext->imageTextureTile(x, y)); + + glBegin(GL_QUADS); + + glTexCoord2f(0.0, 0.0); + glVertex2f(x, y); + + glTexCoord2f(1.0, 0.0); + glVertex2f(x + m_OpenGLImageContext->imageTextureTileWidth(), y); + + glTexCoord2f(1.0, 1.0); + glVertex2f(x + m_OpenGLImageContext->imageTextureTileWidth(), y + m_OpenGLImageContext->imageTextureTileHeight()); + + glTexCoord2f(0.0, 1.0); + glVertex2f(x, y + m_OpenGLImageContext->imageTextureTileHeight()); + + glEnd(); + } + } + + glDisable(GL_TEXTURE_2D); + glDisable(GL_BLEND); + + m_gridManager->drawGrid(wr, 0, true); + m_perspectiveGridManager->drawGrid( wr, 0, true ); + + // Unbind the texture otherwise the ATI driver crashes when the canvas context is + // made current after the textures are deleted following an image resize. + glBindTexture(GL_TEXTURE_2D, 0); + + //paintGuides(); + } + } + + m_canvas->OpenGLWidget()->swapBuffers(); + + paintToolOverlay(TQRegion(canvasRect)); + +#else + Q_UNUSED(canvasRect); +#endif +} + +void KisView::setInputDevice(KisInputDevice inputDevice) +{ + if (inputDevice != m_inputDevice) { + m_inputDevice = inputDevice; + + m_toolManager->setToolForInputDevice(m_inputDevice, inputDevice); + + if (m_toolManager->currentTool() == 0) { + m_toolManager->setCurrentTool(m_toolManager->findTool("tool_brush", m_inputDevice)); + } + else { + m_toolManager->setCurrentTool(m_toolManager->currentTool()); + } + m_toolManager->activateCurrentTool(); + + emit sigInputDeviceChanged(inputDevice); + } + +} + +KisInputDevice KisView::currentInputDevice() const +{ + return m_inputDevice; +} + + +KisCanvas *KisView::kiscanvas() const +{ + return m_canvas; +} + +void KisView::updateCanvas() +{ + if (m_image) { + updateCanvas(m_image->bounds()); + } +} + +void KisView::updateCanvas(TQ_INT32 x, TQ_INT32 y, TQ_INT32 w, TQ_INT32 h) +{ + updateCanvas(TQRect(x, y, w, h)); +} + +void KisView::updateCanvas(const TQRect& imageRect) +{ + if (m_canvas->isOpenGLCanvas()) { + updateOpenGLCanvas(imageRect); + paintOpenGLView(windowToView(imageRect)); + } else { + updateTQPaintDeviceCanvas(imageRect); + //m_canvas->update(windowToView(imageRect)); + m_canvas->tqrepaint(windowToView(imageRect)); + } +} + +void KisView::refreshKisCanvas() +{ + TQRect imageRect = viewToWindow(TQRect(0, 0, m_canvas->width(), m_canvas->height())); + + if (m_image) { + imageRect |= m_image->bounds(); + } + + updateCanvas(imageRect); + + // Enable this if updateCanvas does an m_canvas->update() + //m_canvas->tqrepaint(); +} + +void KisView::selectionDisplayToggled(bool displaySelection) +{ +#ifdef HAVE_GL + if (m_canvas->isOpenGLCanvas()) { + if (m_OpenGLImageContext) { + m_OpenGLImageContext->setSelectionDisplayEnabled(displaySelection); + } + } +#else + Q_UNUSED(displaySelection); +#endif + updateCanvas(); +} + +void KisView::layerUpdateGUI(bool enable) +{ + KisImageSP img = currentImg(); + + KisLayerSP layer; + TQ_INT32 nlayers = 0; + TQ_INT32 nvisible = 0; + + + + if (img) { + layer = img->activeLayer(); + nlayers = img->nlayers(); + nvisible = nlayers - img->nHiddenLayers(); + } + + KisPaintLayer * pl = dynamic_cast<KisPaintLayer*>(layer.data()); + + if (pl && ( m_currentColorChooserDisplay != KisID("BLA") || + pl->paintDevice()->colorSpace()->id() != m_currentColorChooserDisplay)) { + if (pl->paintDevice()->colorSpace()->id() == KisID("WET")) { + m_paletteManager->hideWidget( "hsvwidget" ); + m_paletteManager->hideWidget( "rgbwidget" ); + m_paletteManager->hideWidget( "graywidget" ); + m_paletteManager->hideWidget( "palettewidget" ); + m_paletteManager->showWidget( "watercolor docker" ); + } + else { + m_paletteManager->hideWidget( "watercolor docker" ); + m_paletteManager->showWidget( "palettewidget" ); + m_paletteManager->showWidget( "graywidget" ); + m_paletteManager->showWidget( "rgbwidget" ); + m_paletteManager->showWidget( "hsvwidget" ); + } + m_currentColorChooserDisplay = pl->paintDevice()->colorSpace()->id(); + } + + enable = enable && img && layer && layer->visible() && !layer->locked(); + m_layerDup->setEnabled(enable); + m_layerRm->setEnabled(enable); + m_layerHide->setEnabled(img && layer); + m_layerProperties->setEnabled(enable); + m_layerSaveAs->setEnabled(enable); + m_layerRaise->setEnabled(enable && layer->prevSibling()); + m_layerLower->setEnabled(enable && layer->nextSibling()); + m_layerTop->setEnabled(enable && nlayers > 1 && layer != img->rootLayer()->firstChild()); + m_layerBottom->setEnabled(enable && nlayers > 1 && layer != img->rootLayer()->lastChild()); + + // XXX these should be named layer instead of img + m_imgFlatten->setEnabled(nlayers > 1); + m_imgMergeLayer->setEnabled(nlayers > 1 && layer && layer->nextSibling()); + + + m_selectionManager->updateGUI(); + m_filterManager->updateGUI(); + m_toolManager->updateGUI(); + m_gridManager->updateGUI(); + m_perspectiveGridManager->updateGUI(); + + + KisPartLayer * partLayer = dynamic_cast<KisPartLayer*>(layer.data()); + if (partLayer) { + setCanvasCursor( KisCursor::arrowCursor() ); + } + + if (img && img->activeDevice()) + emit currentColorSpaceChanged(img->activeDevice()->colorSpace()); + + imgUpdateGUI(); +} + + +void KisView::imgUpdateGUI() +{ + KisImageSP img = currentImg(); + + m_imgResizeToLayer->setEnabled(img && img->activeLayer()); + + updateStatusBarProfileLabel(); +} + +static const double zoomLevels[] = { + 1.0 / 500, + 1.0 / 333.333333, + 1.0 / 250, + 1.0 / 200, + 1.0 / 150, + 1.0 / 100, + 1.0 / 66.666667, + 1.0 / 50, + 1.0 / 33.333333, + 1.0 / 25, + 1.0 / 20, + 1.0 / 16, + 1.0 / 12, + 1.0 / 8, + 1.0 / 6, + 1.0 / 4, + 1.0 / 3, + 1.0 / 2, + 1.0 / 1.5, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 12, + 16 +}; + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#define NUM_ZOOM_LEVELS ARRAY_SIZE(zoomLevels) + +#define FIRST_ZOOM_LEVEL_INDEX 0 +#define LAST_ZOOM_LEVEL_INDEX (NUM_ZOOM_LEVELS - 1) + +#define KISVIEW_MIN_ZOOM (zoomLevels[FIRST_ZOOM_LEVEL_INDEX]) +#define KISVIEW_MAX_ZOOM (zoomLevels[LAST_ZOOM_LEVEL_INDEX]) + +double KisView::nextZoomInLevel() const +{ + uint zoomLevelIndex = FIRST_ZOOM_LEVEL_INDEX; + + while (zoom() >= zoomLevels[zoomLevelIndex] && zoomLevelIndex < LAST_ZOOM_LEVEL_INDEX) { + zoomLevelIndex++; + } + + return zoomLevels[zoomLevelIndex]; +} + +double KisView::nextZoomOutLevel(double zoomLevel) const +{ + int zoomLevelIndex = LAST_ZOOM_LEVEL_INDEX; + + while (zoomLevel <= zoomLevels[zoomLevelIndex] && zoomLevelIndex > FIRST_ZOOM_LEVEL_INDEX) { + zoomLevelIndex--; + } + + return zoomLevels[zoomLevelIndex]; +} + +double KisView::nextZoomOutLevel() const +{ + return nextZoomOutLevel(zoom()); +} + +void KisView::zoomAroundPoint(double x, double y, double zf) +{ + // Disable updates while we change the scrollbar settings. + m_canvas->setUpdatesEnabled(false); + m_hScroll->setUpdatesEnabled(false); + m_vScroll->setUpdatesEnabled(false); + + if (x < 0 || y < 0) { + // Zoom about the centre of the current display + KisImageSP img = currentImg(); + + if (img) { + if (m_hScroll->isVisible()) { + KisPoint c = viewToWindow(KisPoint(m_canvas->width() / 2.0, m_canvas->height() / 2.0)); + x = c.x(); + } + else { + x = img->width() / 2.0; + } + + if (m_vScroll->isVisible()) { + KisPoint c = viewToWindow(KisPoint(m_canvas->width() / 2.0, m_canvas->height() / 2.0)); + y = c.y(); + } + else { + y = img->height() / 2.0; + } + } + else { + x = 0; + y = 0; + } + } + + setZoom(zf); + + Q_ASSERT(m_zoomIn); + Q_ASSERT(m_zoomOut); + + updateStatusBarZoomLabel (); + + m_zoomIn->setEnabled(zf < KISVIEW_MAX_ZOOM); + m_zoomOut->setEnabled(zf > KISVIEW_MIN_ZOOM); + resizeEvent(0); + + m_hRuler->setZoom(zf); + m_vRuler->setZoom(zf); + + if (m_hScroll->isVisible()) { + double vcx = m_canvas->width() / 2.0; + TQ_INT32 scrollX = tqRound(x * zoom() - vcx); + m_hScroll->setValue(scrollX); + } + + if (m_vScroll->isVisible()) { + double vcy = m_canvas->height() / 2.0; + TQ_INT32 scrollY = tqRound(y * zoom() - vcy); + m_vScroll->setValue(scrollY); + } + + // Now update everything. + m_canvas->setUpdatesEnabled(true); + m_hScroll->setUpdatesEnabled(true); + m_vScroll->setUpdatesEnabled(true); + m_hScroll->update(); + m_vScroll->update(); + + if (m_canvas->isOpenGLCanvas()) { + paintOpenGLView(TQRect(0, 0, m_canvas->width(), m_canvas->height())); + } else { + refreshKisCanvas(); + } + + emit viewTransformationsChanged(); +} + +void KisView::zoomTo(const KisRect& r) +{ + if (!r.isNull()) { + + double wZoom = fabs(m_canvas->width() / r.width()); + double hZoom = fabs(m_canvas->height() / r.height()); + + double zf = kMin(wZoom, hZoom); + + if (zf < KISVIEW_MIN_ZOOM) { + zf = KISVIEW_MIN_ZOOM; + } + else + if (zf > KISVIEW_MAX_ZOOM) { + zf = KISVIEW_MAX_ZOOM; + } + + zoomAroundPoint(r.center().x(), r.center().y(), zf); + } +} + +void KisView::zoomTo(const TQRect& r) +{ + zoomTo(KisRect(r)); +} + +void KisView::zoomTo(TQ_INT32 x, TQ_INT32 y, TQ_INT32 w, TQ_INT32 h) +{ + zoomTo(KisRect(x, y, w, h)); +} + +void KisView::zoomIn(TQ_INT32 x, TQ_INT32 y) +{ + zoomAroundPoint(x, y, nextZoomInLevel()); +} + +void KisView::zoomOut(TQ_INT32 x, TQ_INT32 y) +{ + zoomAroundPoint(x, y, nextZoomOutLevel()); +} + +void KisView::zoomIn() +{ + slotZoomIn(); +} + +void KisView::zoomOut() +{ + slotZoomOut(); +} + +void KisView::slotZoomIn() +{ + zoomIn(-1, -1); +} + +void KisView::slotZoomOut() +{ + zoomOut(-1, -1); +} + +void KisView::slotActualPixels() +{ + zoomAroundPoint(-1, -1, 1.0); +} + +void KisView::slotActualSize() +{ + //XXX later this should be update to take screen res and image res into consideration + zoomAroundPoint(-1, -1, 1.0); +} + +double KisView::fitToCanvasZoomLevel() const +{ + int fullCanvasWidth = width(); + + if (m_vRuler->isVisible()) { + fullCanvasWidth -= m_vRuler->width(); + } + + int fullCanvasHeight = height(); + + if (m_hRuler->isVisible()) { + fullCanvasHeight -= m_hRuler->height(); + } + + KisImageSP img = currentImg(); + if (img) { + double xZoomLevel = static_cast<double>(fullCanvasWidth) / img->width(); + double yZoomLevel = static_cast<double>(fullCanvasHeight) / img->height(); + + return TQMIN(xZoomLevel, yZoomLevel); + } + else { + return 1; + } +} + +void KisView::slotFitToCanvas() +{ + zoomAroundPoint(-1, -1, fitToCanvasZoomLevel()); +} + +void KisView::setInitialZoomLevel() +{ + double zoomLevel = fitToCanvasZoomLevel(); + + if (zoomLevel > 1) { + zoomLevel = 1; + } else { + zoomLevel = nextZoomOutLevel(zoomLevel); + } + + zoomAroundPoint(-1, -1, zoomLevel); +} + +void KisView::imgResizeToActiveLayer() +{ + KisImageSP img = currentImg(); + KisLayerSP layer; + + if (img && (layer = img->activeLayer())) { + + if (m_adapter && m_adapter->undo()) { + m_adapter->beginMacro(i18n("Resize Image to Size of Current Layer")); + } + + img->lock(); + + TQRect r = layer->exactBounds(); + img->resize(r.width(), r.height(), r.x(), r.y(), true); + + img->unlock(); + + if (m_adapter && m_adapter->undo()) { + m_adapter->endMacro(); + } + } +} + +void KisView::slotImageProperties() +{ + KisImageSP img = currentImg(); + + if (!img) return; + + KisDlgImageProperties dlg(img, this); + + if (dlg.exec() == TQDialog::Accepted) { + if (dlg.imageWidth() != img->width() || + dlg.imageHeight() != img->height()) { + + resizeCurrentImage(dlg.imageWidth(), + dlg.imageHeight()); + } + TQ_INT32 opacity = dlg.opacity(); + opacity = opacity * 255 / 100; + img->setName(dlg.imageName()); + img->setColorSpace(dlg.colorSpace()); + img->setResolution(dlg.resolution(), dlg.resolution()); + img->setDescription(dlg.description()); + img->setProfile(dlg.profile()); + } +} + +void KisView::slotInsertImageAsLayer() +{ + if (importImage() > 0) + m_doc->setModified(true); +} + +void KisView::slotAddPalette() +{ + KDialogBase* base = new KDialogBase(this, 0, true, i18n("Add Palette"), KDialogBase::Ok | KDialogBase::Cancel); + KisCustomPalette* p = new KisCustomPalette(base, "add palette", i18n("Add Palette"), this); + base->setMainWidget(p); + base->show(); +} + +void KisView::slotEditPalette() +{ + KisPaletteChooser chooser(this); + KisResourceServerBase* srv = KisResourceServerRegistry::instance()->get("PaletteServer"); + if (!srv) { + return; + } + TQValueList<KisResource*> resources = srv->resources(); + TQValueList<KisPalette*> palettes; + + for(uint i = 0; i < resources.count(); i++) { + KisPalette* palette = dynamic_cast<KisPalette*>(*resources.at(i)); + + chooser.paletteList->insertItem(palette->name()); + palettes.append(palette); + } + + if (chooser.exec() != TQDialog::Accepted ) { + return; + } + + int index = chooser.paletteList->currentItem(); + if (index < 0) { + KMessageBox::error(this, i18n("No palette selected."), i18n("Palette")); + return; + } + + KDialogBase* base = new KDialogBase(this, 0, true, i18n("Edit Palette") , KDialogBase::Ok); + KisCustomPalette* cp = new KisCustomPalette(base, "edit palette", + i18n("Edit Palette"), this); + cp->setEditMode(true); + cp->setPalette(*palettes.at(index)); + base->setMainWidget(cp); + base->show(); +} + +void KisView::saveLayerAsImage() +{ + TQStringList listMimeFilter = KoFilterManager::mimeFilter("application/x-chalk", KoFilterManager::Export); + TQString mimelist = listMimeFilter.join(" "); + + KFileDialog fd (TQString(), mimelist, this, "Export Layer", true); + fd.setCaption(i18n("Export Layer")); + fd.setMimeFilter(listMimeFilter); + fd.setOperationMode(KFileDialog::Saving); + + if (!fd.exec()) return; + + KURL url = fd.selectedURL(); + TQString mimefilter = fd.currentMimeFilter(); + + if (url.isEmpty()) + return; + + + KisImageSP img = currentImg(); + if (!img) return; + + KisLayerSP l = img->activeLayer(); + if (!l) return; + + TQRect r = l->exactBounds(); + + KisDoc d; + d.prepareForImport(); + + KisImageSP dst = new KisImage(d.undoAdapter(), r.width(), r.height(), img->colorSpace(), l->name()); + d.setCurrentImage( dst ); + dst->addLayer(l->clone(),dst->rootLayer(),0); + + d.setOutputMimeType(mimefilter.latin1()); + d.exp0rt(url); +} + + + +TQ_INT32 KisView::importImage(const KURL& urlArg) +{ + KisImageSP currentImage = currentImg(); + + if (!currentImage) { + return 0; + } + + KURL::List urls; + TQ_INT32 rc = 0; + + if (urlArg.isEmpty()) { + TQString mimelist = KoFilterManager::mimeFilter("application/x-chalk", KoFilterManager::Import).join(" "); + urls = KFileDialog::getOpenURLs(TQString(), mimelist, 0, i18n("Import Image")); + } else { + urls.push_back(urlArg); + } + + if (urls.empty()) + return 0; + + for (KURL::List::iterator it = urls.begin(); it != urls.end(); ++it) { + new KisImportCatcher( *it, currentImage ); + } + + updateCanvas(); + + return rc; +} + +void KisView::rotateLayer180() +{ + rotateLayer( M_PI ); +} + +void KisView::rotateLayerLeft90() +{ + rotateLayer( M_PI/2 - 2*M_PI ); +} + +void KisView::rotateLayerRight90() +{ + rotateLayer( M_PI/2 ); +} + +void KisView::mirrorLayerX() +{ + if (!currentImg()) return; + KisPaintDeviceSP dev = currentImg()->activeDevice(); + if (!dev) return; + + KisTransaction * t = 0; + if (undoAdapter() && undoAdapter()->undo()) { + t = new KisTransaction(i18n("Mirror Layer X"), dev); + Q_CHECK_PTR(t); + } + + dev->mirrorX(); + + if (t) undoAdapter()->addCommand(t); + + m_doc->setModified(true); + layersUpdated(); + updateCanvas(); +} + +void KisView::mirrorLayerY() +{ + if (!currentImg()) return; + KisPaintDeviceSP dev = currentImg()->activeDevice(); + if (!dev) return; + + KisTransaction * t = 0; + if (undoAdapter() && undoAdapter()->undo()) { + t = new KisTransaction(i18n("Mirror Layer Y"), dev); + Q_CHECK_PTR(t); + } + + dev->mirrorY(); + + if (t) undoAdapter()->addCommand(t); + + m_doc->setModified(true); + layersUpdated(); + updateCanvas(); +} + +void KisView::scaleLayer(double sx, double sy, KisFilterStrategy *filterStrategy) +{ + if (!currentImg()) return; + + KisPaintDeviceSP dev = currentImg()->activeDevice(); + if (!dev) return; + + KisSelectedTransaction * t = 0; + if (undoAdapter() && undoAdapter()->undo()) { + t = new KisSelectedTransaction(i18n("Scale Layer"), dev); + Q_CHECK_PTR(t); + } + + KisTransformWorker worker(dev, sx, sy, 0, 0, 0.0, 0, 0, m_progress, filterStrategy); + worker.run(); + + if (t) undoAdapter()->addCommand(t); + currentImg()->rootLayer()->setDirty(false); + m_doc->setModified(true); + layersUpdated(); + updateCanvas(); +} + +void KisView::rotateLayer(double radians) +{ + if (!currentImg()) return; + + KisPaintDeviceSP dev = currentImg()->activeDevice(); + if (!dev) return; + + KisSelectedTransaction * t = 0; + if (undoAdapter() && undoAdapter()->undo()) { + t = new KisSelectedTransaction(i18n("Rotate Layer"), dev); + Q_CHECK_PTR(t); + } + + KisFilterStrategy *filter = KisFilterStrategyRegistry::instance()->get(KisID("Triangle")); + TQRect r; + if(dev->hasSelection()) + r = dev->selection()->selectedExactRect(); + else + r = dev->exactBounds(); + double cx = r.x()+r.width()/2.0; + double cy = r.y()+r.height()/2.0; + TQ_INT32 tx = TQ_INT32(cx*cos(radians) - cy*sin(radians) - cx + 0.5); + TQ_INT32 ty = TQ_INT32(cy*cos(radians) + cx*sin(radians) - cy + 0.5); + + KisTransformWorker tw(dev, 1.0, 1.0, 0, 0, radians, -tx, -ty, m_progress, filter); + tw.run(); + + if (t) undoAdapter()->addCommand(t); + + m_doc->setModified(true); + layersUpdated(); + updateCanvas(); +} + +void KisView::shearLayer(double angleX, double angleY) +{ + if (!currentImg()) return; + + KisLayerSP layer = currentImg()->activeLayer(); + if (!layer) return; + + KisUndoAdapter * undo = 0; + if ((undo = currentImg()->undoAdapter())) { + undo->beginMacro(i18n("Shear layer")); + } + + KisShearVisitor v(angleX, angleY, m_progress); + v.setUndoAdapter(undo); + layer->accept(v); + + if (undo) undo->endMacro(); + + m_doc->setModified(true); + layersUpdated(); + updateCanvas(); +} + +void KisView::flattenImage() +{ + KisImageSP img = currentImg(); + + if (img) { + bool doIt = true; + + if (img->nHiddenLayers() > 0) { + int answer = KMessageBox::warningYesNo(this, + i18n("The image contains hidden layers that will be lost."), + i18n("Flatten Image"), + i18n("&Flatten Image"), + KStdGuiItem::cancel()); + + if (answer != KMessageBox::Yes) { + doIt = false; + } + } + + if (doIt) { + img->flatten(); + } + } +} + +void KisView::mergeLayer() +{ + KisImageSP img = currentImg(); + if (!img) return; + + KisLayerSP layer = img->activeLayer(); + if (!layer) return; + + img->mergeLayer(layer); +} + +void KisView::preferences() +{ +#ifdef HAVE_GL + bool canvasWasOpenGL = m_canvas->isOpenGLCanvas(); +#endif + + if (PreferencesDialog::editPreferences()) + { + KisConfig cfg; + m_paletteManager->slotResetFont(); + resetMonitorProfile(); + +#ifdef HAVE_GL + if (cfg.useOpenGL() != canvasWasOpenGL) { + + disconnectCurrentImg(); + + //XXX: Need to notify other views that this global setting has changed. + if (cfg.useOpenGL()) { + m_OpenGLImageContext = KisOpenGLImageContext::getImageContext(m_image, monitorProfile()); + m_canvas->createOpenGLCanvas(m_OpenGLImageContext->sharedContextWidget()); + } else + { + m_OpenGLImageContext = 0; + m_canvas->createTQPaintDeviceCanvas(); + } + + connectCurrentImg(); + + resizeEvent(0); + } + + if (cfg.useOpenGL()) { + m_OpenGLImageContext->setMonitorProfile(monitorProfile()); + } +#endif + + refreshKisCanvas(); + + if (m_toolManager->currentTool()) { + setCanvasCursor(m_toolManager->currentTool()->cursor()); + } + +#if defined(EXTENDED_X11_TABLET_SUPPORT) + m_canvas->selectTabletDeviceEvents(); +#endif + + } +} + +void KisView::layerCompositeOp(const KisCompositeOp& compositeOp) +{ + KisImageSP img = currentImg(); + if (!img) return; + + KisLayerSP layer = img->activeLayer(); + if (!layer) return; + + if (img->undo()) { + KNamedCommand *cmd = layer->setCompositeOpCommand(compositeOp); + cmd->execute(); + undoAdapter()->addCommand(cmd); + } +} + +// range: 0 - 100 +void KisView::layerOpacity(int opacity, bool dontundo) +{ + KisImageSP img = currentImg(); + if (!img) return; + + KisLayerSP layer = img->activeLayer(); + if (!layer) return; + + opacity = int(float(opacity * 255) / 100 + 0.5); + if (opacity > 255) + opacity = 255; + + if (opacity == layer->opacity()) return; + + if (dontundo) + layer->setOpacity( opacity ); + else + { + if (img->undo()) { + KNamedCommand *cmd = layer->setOpacityCommand(opacity); + cmd->execute(); + undoAdapter()->addCommand(cmd); + } + } +} + +void KisView::layerOpacityFinishedChanging( int previous, int opacity ) +{ + KisImageSP img = currentImg(); + if (!img) return; + + KisLayerSP layer = img->activeLayer(); + if (!layer) return; + + opacity = int(float(opacity * 255) / 100 + 0.5); + if (opacity > 255) + opacity = 255; + + previous = int(float(previous * 255) / 100 + 0.5); + if (previous > 255) + previous = 255; + + if (previous == opacity) return; + + if (img->undo()) { + KNamedCommand *cmd = layer->setOpacityCommand(previous, opacity); + m_adapter->addCommand(cmd); + } +} + + +void KisView::showRuler() +{ + if( m_RulerAction->isChecked() ) + { + m_hRuler->show(); + m_vRuler->show(); + } + else + { + m_hRuler->hide(); + m_vRuler->hide(); + } + + resizeEvent(0); + refreshKisCanvas(); +} + +void KisView::slotUpdateFullScreen(bool toggle) +{ + if (KoView::shell()) { + + uint newState = KoView::shell()->windowState(); + + if (toggle) { + newState |= TQt::WindowFullScreen; + } else { + newState &= ~TQt::WindowFullScreen; + } + + KoView::shell()->setWindowState(newState); + } +} + +TQ_INT32 KisView::docWidth() const +{ + return currentImg() ? currentImg()->width() : 0; +} + +TQ_INT32 KisView::docHeight() const +{ + return currentImg() ? currentImg()->height() : 0; +} + +void KisView::scrollTo(TQ_INT32 x, TQ_INT32 y) +{ + if (m_hScroll->isVisible()) { + m_hScroll->setValue(x); + } + if (m_vScroll->isVisible()) { + m_vScroll->setValue(y); + } +} + +void KisView::brushActivated(KisResource *brush) +{ + + m_brush = dynamic_cast<KisBrush*>(brush); + + if (m_brush ) + { + emit brushChanged(m_brush); + notifyObservers(); + } +} + +void KisView::patternActivated(KisResource *pattern) +{ + m_pattern = dynamic_cast<KisPattern*>(pattern); + + if (m_pattern) { + emit patternChanged(m_pattern); + notifyObservers(); + } +} + +void KisView::gradientActivated(KisResource *gradient) +{ + + m_gradient = dynamic_cast<KisGradient*>(gradient); + + if (m_gradient) { + emit gradientChanged(m_gradient); + notifyObservers(); + } +} + +void KisView::paintopActivated(const KisID & paintop, const KisPaintOpSettings *paintopSettings) +{ + if (paintop.id().isNull() || paintop.id().isEmpty()) { + return; + } + + m_paintop = paintop; + m_paintopSettings = paintopSettings; + emit paintopChanged(m_paintop, paintopSettings); + notifyObservers(); +} + +void KisView::setBGColor(const KisColor& c) +{ + m_bg = c; + notifyObservers(); + emit sigBGQColorChanged( c.toTQColor() ); +} + +void KisView::setFGColor(const KisColor& c) +{ + m_fg = c; + notifyObservers(); + emit sigFGQColorChanged( c.toTQColor() ); +} + +void KisView::slotSetFGColor(const KisColor& c) +{ + + m_fg = c; + notifyObservers(); +} + +void KisView::slotSetBGColor(const KisColor& c) +{ + + m_bg = c; + notifyObservers(); +} + +void KisView::slotSetFGQColor(const TQColor& c) +{ + KisColorSpace * monitorSpace = KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA"), m_monitorProfile); + setFGColor(KisColor(c, monitorSpace)); + emit sigFGQColorChanged(c); +} + +void KisView::slotSetBGQColor(const TQColor& c) +{ + KisColorSpace * monitorSpace = KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA"), m_monitorProfile); + setBGColor(KisColor(c, monitorSpace)); + emit sigBGQColorChanged(c); +} + + +void KisView::setupPrinter(KPrinter& printer) +{ + KisImageSP img = currentImg(); + + if (img) { + printer.setPageSelection(KPrinter::ApplicationSide); + printer.setPageSize(KPrinter::A4); + printer.setOrientation(KPrinter::Portrait); + } +} + +void KisView::print(KPrinter& printer) +{ + TQPainter gc(&printer); + + KisImageSP img = currentImg(); + if (!img) return; + + printer.setFullPage(true); + gc.setClipping(false); + + KisConfig cfg; + TQString printerProfileName = cfg.printerProfile(); + KisProfile * printerProfile = KisMetaRegistry::instance()->csRegistry() ->getProfileByName(printerProfileName); + + TQRect r = img->bounds(); + img->renderToPainter(r.x(), r.y(), r.width(), r.height(), gc, printerProfile, KisImage::PAINT_IMAGE_ONLY, HDRExposure()); +} + +void KisView::paintToolOverlay(const TQRegion& region) +{ + if (!region.isEmpty() && m_toolManager->currentTool() && !m_toolIsPainting) { + KisCanvasPainter gc(m_canvas); + + gc.setClipRegion(region); + gc.setClipping(true); + + // Prevent endless loop if the tool needs to have the canvas tqrepainted + m_toolIsPainting = true; + m_toolManager->currentTool()->paint(gc, region.boundingRect()); + m_toolIsPainting = false; + } +} + +void KisView::canvasGotPaintEvent(TQPaintEvent *event) +{ + if (m_canvas->isOpenGLCanvas()) { + paintOpenGLView(event->rect()); + } else { + paintTQPaintDeviceView(event->region()); + } +} + +void KisView::canvasGotButtonPressEvent(KisButtonPressEvent *e) +{ +#if defined(EXTENDED_X11_TABLET_SUPPORT) + // The event filter doesn't see tablet events going to the canvas. + if (e->device() != KisInputDevice::mouse()) { + m_tabletEventTimer.start(); + } +#endif // EXTENDED_X11_TABLET_SUPPORT + + if (e->device() != currentInputDevice()) { + if (e->device() == KisInputDevice::mouse()) { + if (m_tabletEventTimer.elapsed() > MOUSE_CHANGE_EVENT_DELAY) { + setInputDevice(KisInputDevice::mouse()); + } + } else { + setInputDevice(e->device()); + } + } + + KisImageSP img = currentImg(); + +// if (img) { +// TQPoint pt = mapToScreen(e->pos().floorTQPoint()); +// KisGuideMgr *mgr = img->guides(); +// +// m_lastGuidePoint = mapToScreen(e->pos().floorTQPoint()); +// m_currentGuide = 0; +// +// if ((e->state() & ~TQt::ShiftButton) == Qt::NoButton) { +// KisGuideSP gd = mgr->tqfind(static_cast<TQ_INT32>(pt.x() / zoom()), static_cast<TQ_INT32>(pt.y() / zoom()), TQMAX(2.0, 2.0 / zoom())); +// +// if (gd) { +// m_currentGuide = gd; +// +// if ((e->button() == Qt::RightButton) || ((e->button() & TQt::ShiftButton) == TQt::ShiftButton)) { +// if (gd->isSelected()) +// mgr->unselect(gd); +// else +// mgr->select(gd); +// } else { +// if (!gd->isSelected()) { +// mgr->unselectAll(); +// mgr->select(gd); +// } +// } +// +// updateGuides(); +// return; +// } +// } +// } + if (e->button() == Qt::RightButton) { + TQPopupMenu * m_popup = 0; + if (factory()) { + Q_ASSERT(factory()); + m_popup = (TQPopupMenu *)factory()->container("image_popup", this); + } + if (m_popup) { + m_popup->popup(e->globalPos().roundTQPoint()); + } + } + else if (e->device() == currentInputDevice() && m_toolManager->currentTool()) { + KisPoint p = viewToWindow(e->pos()); + // somewhat of a hack: we should actually test if we intersect with the scrollers, + // but the globalPos seems to be off by a few pixels + if (m_vScroll->draggingSlider() || m_hScroll->draggingSlider()) + return; + + if (m_toolManager->currentTool()->wantsAutoScroll()) { + enableAutoScroll(); + } + + KisButtonPressEvent ev(e->device(), p, e->globalPos(), e->pressure(), e->xTilt(), e->yTilt(), e->button(), e->state()); + m_toolManager->currentTool()->buttonPress(&ev); + } +} + +void KisView::canvasGotMoveEvent(KisMoveEvent *e) +{ +#if defined(EXTENDED_X11_TABLET_SUPPORT) + // The event filter doesn't see tablet events going to the canvas. + if (e->device() != KisInputDevice::mouse()) { + m_tabletEventTimer.start(); + } +#endif // EXTENDED_X11_TABLET_SUPPORT + + if (e->device() != currentInputDevice()) { + if (e->device() == KisInputDevice::mouse()) { + if (m_tabletEventTimer.elapsed() > MOUSE_CHANGE_EVENT_DELAY) { + setInputDevice(KisInputDevice::mouse()); + } + } else { + setInputDevice(e->device()); + } + } + + KisImageSP img = currentImg(); + + m_hRuler->updatePointer(e->pos().floorX() - m_canvasXOffset, e->pos().floorY() - m_canvasYOffset); + m_vRuler->updatePointer(e->pos().floorX() - m_canvasXOffset, e->pos().floorY() - m_canvasYOffset); + + KisPoint wp = viewToWindow(e->pos()); + +#if 0 + if (img && m_currentGuide) { + TQPoint p = mapToScreen(e->pos().floorTQPoint()); + KisGuideMgr *mgr = img->guides(); + + if (((e->state() & Qt::LeftButton) == Qt::LeftButton) && mgr->hasSelected()) { + eraseGuides(); + p -= m_lastGuidePoint; + + if (p.x()) + mgr->moveSelectedByX(p.x() / zoom()); + + if (p.y()) + mgr->moveSelectedByY(p.y() / zoom()); + + m_doc->setModified(true); + paintGuides(); + } + } else +#endif + if (e->device() == currentInputDevice() && m_toolManager->currentTool()) { + KisMoveEvent ev(e->device(), wp, e->globalPos(), e->pressure(), e->xTilt(), e->yTilt(), e->state()); + + m_toolManager->currentTool()->move(&ev); + } + +// m_lastGuidePoint = mapToScreen(e->pos().floorTQPoint()); + emit cursorPosition(wp.floorX(), wp.floorY()); +} + +int KisView::leftBorder() const +{ + return m_rulerThickness; +} + +int KisView::rightBorder() const +{ + return m_hScrollBarExtent; +} + +int KisView::topBorder() const +{ + return m_rulerThickness; +} + +int KisView::bottomBorder() const +{ + return m_vScrollBarExtent; +} + +void KisView::mouseMoveEvent(TQMouseEvent *e) +{ + KisMoveEvent ke(currentInputDevice(), KisPoint(e->pos()), KisPoint(e->globalPos()), PRESSURE_DEFAULT, 0, 0, e->state()); + canvasGotMoveEvent(&ke); +} + +void KisView::slotAutoScroll(const TQPoint &p) +{ + scrollTo(horzValue()+p.x(), vertValue()+p.y()); +} + +void KisView::canvasGotButtonReleaseEvent(KisButtonReleaseEvent *e) +{ +#if defined(EXTENDED_X11_TABLET_SUPPORT) + // The event filter doesn't see tablet events going to the canvas. + if (e->device() != KisInputDevice::mouse()) { + m_tabletEventTimer.start(); + } +#endif // EXTENDED_X11_TABLET_SUPPORT + + if (e->device() != currentInputDevice()) { + if (e->device() == KisInputDevice::mouse()) { + if (m_tabletEventTimer.elapsed() > MOUSE_CHANGE_EVENT_DELAY) { + setInputDevice(KisInputDevice::mouse()); + } + } else { + setInputDevice(e->device()); + } + } + + KisImageSP img = currentImg(); + +// if (img && m_currentGuide) { +// m_currentGuide = 0; +// } else + if (e->device() == currentInputDevice() && m_toolManager->currentTool()) { + KisPoint p = viewToWindow(e->pos()); + KisButtonReleaseEvent ev(e->device(), p, e->globalPos(), e->pressure(), e->xTilt(), e->yTilt(), e->button(), e->state()); + + disableAutoScroll(); + if (m_toolManager->currentTool()) { + m_toolManager->currentTool()->buttonRelease(&ev); + } + } +} + +void KisView::canvasGotDoubleClickEvent(KisDoubleClickEvent *e) +{ +#if defined(EXTENDED_X11_TABLET_SUPPORT) + // The event filter doesn't see tablet events going to the canvas. + if (e->device() != KisInputDevice::mouse()) { + m_tabletEventTimer.start(); + } +#endif // EXTENDED_X11_TABLET_SUPPORT + + if (e->device() != currentInputDevice()) { + if (e->device() == KisInputDevice::mouse()) { + if (m_tabletEventTimer.elapsed() > MOUSE_CHANGE_EVENT_DELAY) { + setInputDevice(KisInputDevice::mouse()); + } + } else { + setInputDevice(e->device()); + } + } + + if (e->device() == currentInputDevice() && m_toolManager->currentTool()) { + KisPoint p = viewToWindow(e->pos()); + KisDoubleClickEvent ev(e->device(), p, e->globalPos(), e->pressure(), e->xTilt(), e->yTilt(), e->button(), e->state()); + + if (m_toolManager->currentTool()) { + m_toolManager->currentTool()->doubleClick(&ev); + } + } +} + +void KisView::canvasGotEnterEvent(TQEvent *e) +{ + Q_UNUSED( e ); +} + +void KisView::canvasGotLeaveEvent (TQEvent *e) +{ + Q_UNUSED( e ); +} + +void KisView::canvasGotMouseWheelEvent(TQWheelEvent *event) +{ + //if(event->state() == ControlButton ) + //{ + if(event->delta() / 120 != 0) + { + if(event->delta() > 0) + { + zoomIn(); + } else { + zoomOut(); + } + if (m_oldTool) { + KisCanvasPainter gc(m_canvas); + m_oldTool->paint(gc); + } + } + //} else { + // TQApplication::sendEvent(m_vScroll, event); + //} +} + +void KisView::canvasGotKeyPressEvent(TQKeyEvent *event) +{ + if (!m_toolManager->currentTool()) { + event->ignore(); + return; + } + + if (event->key() == TQt::Key_Space) { + if (!m_panning) { + // Set tool temporarily to pan + m_panning = true; + m_oldTool = m_toolManager->currentTool(); + m_toolManager->setCurrentTool( "tool_pan" ); + } + else { + // Unset panning + m_panning = false; + m_toolManager->setCurrentTool( m_oldTool ); + m_oldTool = 0; + } + } + if (m_toolManager->currentTool()) + m_toolManager->currentTool()->keyPress(event); +} + +void KisView::canvasGotKeyReleaseEvent(TQKeyEvent *event) +{ + if (m_toolManager->currentTool()) + m_toolManager->currentTool()->keyRelease(event); +} + +void KisView::canvasGotDragEnterEvent(TQDragEnterEvent *event) +{ + bool accept = false; + + // Only accept drag if we're not busy, particularly as we may + // be showing a progress bar and calling tqApp->processEvents(). + if (KURLDrag::canDecode(event) && TQApplication::overrideCursor() == 0) { + accept = true; + } + + event->accept(accept); +} + +void KisView::canvasGotDropEvent(TQDropEvent *event) +{ + KURL::List urls; + + if (KURLDrag::decode(event, urls)) + { + if (urls.count() > 0) { + enum enumActionId { + addLayerId = 1, + addDocumentId = 2, + cancelId + }; + + KPopupMenu popup(this, "drop_popup"); + + if (urls.count() == 1) { + if (currentImg() != 0) { + popup.insertItem(i18n("Insert as New Layer"), addLayerId); + } + popup.insertItem(i18n("Open in New Document"), addDocumentId); + } + else { + if (currentImg() != 0) { + popup.insertItem(i18n("Insert as New Layers"), addLayerId); + } + popup.insertItem(i18n("Open in New Documents"), addDocumentId); + } + + popup.insertSeparator(); + popup.insertItem(i18n("Cancel"), cancelId); + + int actionId = popup.exec(TQCursor::pos()); + + if (actionId >= 0 && actionId != cancelId) { + for (KURL::List::ConstIterator it = urls.begin (); it != urls.end (); ++it) { + KURL url = *it; + + switch (actionId) { + case addLayerId: + importImage(url); + break; + case addDocumentId: + if (shell() != 0) { + shell()->openDocument(url); + } + break; + } + } + } + } + } +} + +void KisView::layerProperties() +{ + if (currentImg() && currentImg()->activeLayer()) + showLayerProperties(currentImg()->activeLayer()); +} + +namespace { + class KisChangeFilterCmd : public KNamedCommand { + typedef KNamedCommand super; + + public: + // The TQStrings are the _serialized_ configs + KisChangeFilterCmd(KisAdjustmentLayerSP layer, + KisFilterConfiguration* config, + const TQString& before, + const TQString& after) : super(i18n("Change Filter")) + { + m_layer = layer; + m_config = config; + m_before = before; + m_after = after; + } + public: + virtual void execute() + { + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + m_config->fromXML(m_after); + //Q_ASSERT(m_after == m_config->toString()); + m_layer->setFilter(m_config); + m_layer->setDirty(); + TQApplication::restoreOverrideCursor(); + } + + virtual void unexecute() + { + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + m_config->fromXML(m_before); + //Q_ASSERT(m_before == m_config->toString()); + m_layer->setFilter(m_config); + m_layer->setDirty(); + TQApplication::restoreOverrideCursor(); + } + private: + KisAdjustmentLayerSP m_layer; + KisFilterConfiguration* m_config; + TQString m_before; + TQString m_after; + }; +} + +void KisView::showLayerProperties(KisLayerSP layer) +{ + Q_ASSERT( layer ); + if ( !layer ) return; + + KisColorSpace * cs = 0; + KisPaintLayer * pl = dynamic_cast<KisPaintLayer*>( layer.data() ); + if ( pl ) { + cs = pl->paintDevice()->colorSpace(); + } + else { + cs = layer->image()->colorSpace(); + } + + + if (KisAdjustmentLayerSP alayer = dynamic_cast<KisAdjustmentLayer*>(layer.data())) + { + KisDlgAdjLayerProps dlg(alayer, alayer->name(), i18n("Adjustment Layer Properties"), this, "dlgadjlayerprops"); + TQString before = dlg.filterConfiguration()->toString(); + if (dlg.exec() == TQDialog::Accepted) + { + KisChangeFilterCmd * cmd = new KisChangeFilterCmd(alayer, + dlg.filterConfiguration(), + before, + dlg.filterConfiguration()->toString()); + cmd->execute(); + m_adapter->addCommand(cmd); + m_doc->setModified( true ); + } + } + else + { + KisDlgLayerProperties dlg(layer->name(), + layer->opacity(), + layer->compositeOp(), + cs); + if (dlg.exec() == TQDialog::Accepted) + { + if (layer->name() != dlg.getName() || + layer->opacity() != dlg.getOpacity() || + layer->compositeOp() != dlg.getCompositeOp()) + { + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + m_adapter->beginMacro(i18n("Property Changes")); + layer->image()->setLayerProperties(layer, dlg.getOpacity(), dlg.getCompositeOp(), dlg.getName()); + layer->setDirty(); + m_adapter->endMacro(); + TQApplication::restoreOverrideCursor(); + m_doc->setModified( true ); + } + } + } +} + +void KisView::layerAdd() +{ + KisImageSP img = currentImg(); + if (img && img->activeLayer()) { + addLayer(img->activeLayer()->tqparent(), img->activeLayer()); + } + else if (img) + addLayer(static_cast<KisGroupLayer*>(img->rootLayer().data()), 0); +} + +void KisView::addLayer(KisGroupLayerSP tqparent, KisLayerSP above) +{ + KisImageSP img = currentImg(); + if (img) { + KisConfig cfg; + TQString profilename; + if(img->colorSpace()->getProfile()) + profilename = img->colorSpace()->getProfile()->productName(); + NewLayerDialog dlg(img->colorSpace()->id(), profilename, img->nextLayerName(), this); + + if (dlg.exec() == TQDialog::Accepted) { + KisColorSpace* cs = KisMetaRegistry::instance()-> csRegistry() -> + getColorSpace(dlg.colorSpaceID(),dlg.profileName()); + KisLayerSP layer = new KisPaintLayer(img, dlg.layerName(), dlg.opacity(), cs); + if (layer) { + layer->setCompositeOp(dlg.compositeOp()); + img->addLayer(layer, tqparent.data(), above); + updateCanvas(); + } else { + KMessageBox::error(this, i18n("Could not add layer to image."), i18n("Layer Error")); + } + } + else { + img->rollBackLayerName(); + } + } +} + +void KisView::addGroupLayer(KisGroupLayerSP tqparent, KisLayerSP above) +{ + KisImageSP img = currentImg(); + if (img) { + TQString profilename; + if(img->colorSpace()->getProfile()) + profilename = img->colorSpace()->getProfile()->productName(); + KisConfig cfg; + NewLayerDialog dlg(img->colorSpace()->id(), profilename, img->nextLayerName(), this); + dlg.setColorSpaceEnabled(false); + + if (dlg.exec() == TQDialog::Accepted) { + KisLayerSP layer = new KisGroupLayer(img, dlg.layerName(), dlg.opacity()); + if (layer) { + layer->setCompositeOp(dlg.compositeOp()); + img->addLayer(layer, tqparent.data(), above); + updateCanvas(); + } else { + KMessageBox::error(this, i18n("Could not add layer to image."), i18n("Layer Error")); + } + } + } +} + +void KisView::addPartLayer() +{ + KisImageSP img = currentImg(); + if (!img) return; + + addPartLayer(img->rootLayer(), img->rootLayer()->firstChild(), m_actionPartLayer->documentEntry()); +} + +void KisView::addPartLayer(KisGroupLayerSP tqparent, KisLayerSP above, const KoDocumentEntry& entry) +{ + delete m_partHandler; // Only one at a time + m_partHandler = new KisPartLayerHandler(this, entry, tqparent, above); + + disconnect(m_canvas, TQT_SIGNAL(sigGotButtonPressEvent(KisButtonPressEvent*)), this, 0); + disconnect(m_canvas, TQT_SIGNAL(sigGotButtonReleaseEvent(KisButtonReleaseEvent*)), this, 0); + disconnect(m_canvas, TQT_SIGNAL(sigGotMoveEvent(KisMoveEvent*)), this, 0); + disconnect(m_canvas, TQT_SIGNAL(sigGotKeyPressEvent(TQKeyEvent*)), this, 0); + + connect(m_canvas, TQT_SIGNAL(sigGotButtonPressEvent(KisButtonPressEvent*)), + m_partHandler, TQT_SLOT(gotButtonPressEvent(KisButtonPressEvent*))); + connect(m_canvas, TQT_SIGNAL(sigGotButtonReleaseEvent(KisButtonReleaseEvent*)), + m_partHandler, TQT_SLOT(gotButtonReleaseEvent(KisButtonReleaseEvent*))); + connect(m_canvas, TQT_SIGNAL(sigGotMoveEvent(KisMoveEvent*)), + m_partHandler, TQT_SLOT(gotMoveEvent(KisMoveEvent*))); + connect(m_canvas, TQT_SIGNAL(sigGotKeyPressEvent(TQKeyEvent*)), + m_partHandler, TQT_SLOT(gotKeyPressEvent(TQKeyEvent*))); + + connect(m_partHandler, TQT_SIGNAL(sigGotMoveEvent(KisMoveEvent*)), + TQT_TQOBJECT(this), TQT_SLOT(canvasGotMoveEvent(KisMoveEvent*))); + connect(m_partHandler, TQT_SIGNAL(sigGotKeyPressEvent(TQKeyEvent*)), + TQT_TQOBJECT(this), TQT_SLOT(canvasGotKeyPressEvent(TQKeyEvent*))); + connect(m_partHandler, TQT_SIGNAL(handlerDone()), + TQT_TQOBJECT(this), TQT_SLOT(reconnectAfterPartInsert())); +} + +void KisView::insertPart(const TQRect& viewRect, const KoDocumentEntry& entry, + KisGroupLayerSP tqparent, KisLayerSP above) { + KisImageSP img = currentImg(); + if (!img) return; + + KoDocument* doc = entry.createDoc(m_doc); + if ( !doc ) + return; + + if ( !doc->showEmbedInitDialog(this) ) + return; + + TQRect rect = viewToWindow(viewRect); + + KisChildDoc * childDoc = m_doc->createChildDoc(rect, doc); + + KisPartLayerImpl* partLayer = new KisPartLayerImpl(img, childDoc); + partLayer->setDocType(entry.service()->genericName()); + img->addLayer(partLayer, tqparent, above); + m_doc->setModified(true); + + reconnectAfterPartInsert(); +} + +void KisView::reconnectAfterPartInsert() { + connect(m_canvas, TQT_SIGNAL(sigGotButtonPressEvent(KisButtonPressEvent*)), + TQT_TQOBJECT(this), TQT_SLOT(canvasGotButtonPressEvent(KisButtonPressEvent*))); + connect(m_canvas, TQT_SIGNAL(sigGotButtonReleaseEvent(KisButtonReleaseEvent*)), + TQT_TQOBJECT(this), TQT_SLOT(canvasGotButtonReleaseEvent(KisButtonReleaseEvent*))); + connect(m_canvas, TQT_SIGNAL(sigGotMoveEvent(KisMoveEvent*)), + TQT_TQOBJECT(this), TQT_SLOT(canvasGotMoveEvent(KisMoveEvent*))); + connect(m_canvas, TQT_SIGNAL(sigGotKeyPressEvent(TQKeyEvent*)), + TQT_TQOBJECT(this), TQT_SLOT(canvasGotKeyPressEvent(TQKeyEvent*))); + + delete m_partHandler; + m_partHandler = 0; +} + +void KisView::addAdjustmentLayer() +{ + KisImageSP img = currentImg(); + if (!img) return; + + addAdjustmentLayer( img->activeLayer()->tqparent(), img->activeLayer() ); +} + +void KisView::addAdjustmentLayer(KisGroupLayerSP tqparent, KisLayerSP above) +{ + Q_ASSERT(tqparent); + Q_ASSERT(above); + + KisImageSP img = currentImg(); + if (!img) return; + + KisLayerSP l = img->activeLayer(); + + KisPaintDeviceSP dev; + + // Argh! I hate having to cast, cast and cast again to see what kind of a layer I've got! + KisPaintLayer * pl = dynamic_cast<KisPaintLayer*>(l.data()); + if (pl) { + dev = pl->paintDevice(); + } + else { + KisGroupLayer * gl = dynamic_cast<KisGroupLayer*>(l.data()); + if (gl) { + dev = gl->projection(img->bounds()); + } + else { + KisAdjustmentLayer * al = dynamic_cast<KisAdjustmentLayer*>(l.data()); + if (al) { + dev = al->cachedPaintDevice(); + } + else { + return; + } + } + } + + KisDlgAdjustmentLayer dlg(img, img->nextLayerName(), i18n("New Adjustment Layer"), this, "dlgadjustmentlayer"); + if (dlg.exec() == TQDialog::Accepted) { + KisSelectionSP selection = 0; + if (dev->hasSelection()) { + selection = dev->selection(); + } + KisFilterConfiguration * filter = dlg.filterConfiguration(); + TQString name = dlg.layerName(); + + addAdjustmentLayer( tqparent, above, name, filter, selection); + + } +} + +void KisView::addAdjustmentLayer(KisGroupLayerSP tqparent, KisLayerSP above, const TQString & name, + KisFilterConfiguration * filter, KisSelectionSP selection) +{ + Q_ASSERT(tqparent); + Q_ASSERT(above); + Q_ASSERT(filter); + + KisImageSP img = currentImg(); + if (!img) return; + + KisAdjustmentLayer * l = new KisAdjustmentLayer(img, name, filter, selection); + img->addLayer(l, tqparent, above); +} + +void KisView::slotChildActivated(bool a) { + // It should be so that the only part (child) we can activate, is the current layer: + if (currentImg() && currentImg()->activeLayer()) + { + if (a) { + currentImg()->activeLayer()->activate(); + } else { + currentImg()->activeLayer()->deactivate(); + } + } + + super::slotChildActivated(a); +} + +void KisView::layerRemove() +{ + KisImageSP img = currentImg(); + + if (img) { + KisLayerSP layer = img->activeLayer(); + + if (layer) { + + + img->removeLayer(layer); + + if (layer->tqparent()) + layer->tqparent()->setDirty(layer->extent()); + + updateCanvas(); + layerUpdateGUI(img->activeLayer() != 0); + } + } +} + +void KisView::layerDuplicate() +{ + KisImageSP img = currentImg(); + + if (!img) + return; + + KisLayerSP active = img->activeLayer(); + + if (!active) + return; + + KisLayerSP dup = active->clone(); + dup->setName(i18n("Duplicate of '%1'").tqarg(active->name())); + img->addLayer(dup, active->tqparent().data(), active); + if (dup) { + img->activate( dup ); + updateCanvas(); + } else { + KMessageBox::error(this, i18n("Could not add layer to image."), i18n("Layer Error")); + } +} + +void KisView::layerRaise() +{ + KisImageSP img = currentImg(); + KisLayerSP layer; + + if (!img) + return; + + layer = img->activeLayer(); + + img->raiseLayer(layer); +} + +void KisView::layerLower() +{ + KisImageSP img = currentImg(); + KisLayerSP layer; + + if (!img) + return; + + layer = img->activeLayer(); + + img->lowerLayer(layer); +} + +void KisView::layerFront() +{ + KisImageSP img = currentImg(); + KisLayerSP layer; + + if (!img) + return; + + layer = img->activeLayer(); + img->toTop(layer); +} + +void KisView::layerBack() +{ + KisImageSP img = currentImg(); + if (!img) return; + + KisLayerSP layer; + + layer = img->activeLayer(); + img->toBottom(layer); +} + +void KisView::layersUpdated() +{ + KisImageSP img = currentImg(); + if (!img) return; + + KisLayerSP layer = img->activeLayer(); + + layerUpdateGUI(img && layer); + + notifyObservers(); +} + +void KisView::layerToggleVisible() +{ + KisImageSP img = currentImg(); + if (!img) return; + + KisLayerSP layer = img->activeLayer(); + if (!layer) return; + + layer->setVisible(!layer->visible()); +} + +void KisView::layerToggleLocked() +{ + KisImageSP img = currentImg(); + if (!img) return; + + KisLayerSP layer = img->activeLayer(); + if (!layer) return; + + layer->setLocked(!layer->locked()); +} + +void KisView::actLayerVisChanged(int show) +{ + m_actLayerVis = (show != 0); +} + +bool KisView::activeLayerHasSelection() +{ + return m_image && m_image->activeDevice() && m_image->activeDevice()->hasSelection(); +} + +void KisView::scrollH(int value) +{ + m_hRuler->updateVisibleArea(value, 0); + + int xShift = m_scrollX - value; + m_scrollX = value; + + if (m_canvas->isUpdatesEnabled()) { + if (xShift > 0) { + + if (m_canvas->isOpenGLCanvas()) { + paintOpenGLView(TQRect(0, 0, m_canvas->width(), m_canvas->height())); + } else { + TQRect drawRect(0, 0, xShift, m_canvasPixmap.height()); + + bitBlt(&m_canvasPixmap, xShift, 0, &m_canvasPixmap, 0, 0, m_canvasPixmap.width() - xShift, m_canvasPixmap.height()); + + updateTQPaintDeviceCanvas(viewToWindow(drawRect)); + m_canvas->tqrepaint(); + } + } else if (xShift < 0) { + + TQRect drawRect(m_canvasPixmap.width() + xShift, 0, -xShift, m_canvasPixmap.height()); + + if (m_canvas->isOpenGLCanvas()) { + paintOpenGLView(TQRect(0, 0, m_canvas->width(), m_canvas->height())); + } else { + bitBlt(&m_canvasPixmap, 0, 0, &m_canvasPixmap, -xShift, 0, m_canvasPixmap.width() + xShift, m_canvasPixmap.height()); + + updateTQPaintDeviceCanvas(viewToWindow(drawRect)); + m_canvas->tqrepaint(); + } + } + if (m_oldTool) { + KisCanvasPainter gc(m_canvas); + m_oldTool->paint(gc); + } + } + + if (xShift != 0) { + // XXX do sth with the childframe or so + } + emit viewTransformationsChanged(); +} + +void KisView::scrollV(int value) +{ + m_vRuler->updateVisibleArea(0, value); + + int yShift = m_scrollY - value; + m_scrollY = value; + + if (m_canvas->isUpdatesEnabled()) { + if (yShift > 0) { + + if (m_canvas->isOpenGLCanvas()) { + paintOpenGLView(TQRect(0, 0, m_canvas->width(), m_canvas->height())); + } else { + TQRect drawRect(0, 0, m_canvasPixmap.width(), yShift); + + bitBlt(&m_canvasPixmap, 0, yShift, &m_canvasPixmap, 0, 0, m_canvasPixmap.width(), m_canvasPixmap.height() - yShift); + + updateTQPaintDeviceCanvas(viewToWindow(drawRect)); + m_canvas->tqrepaint(); + } + } else if (yShift < 0) { + + if (m_canvas->isOpenGLCanvas()) { + paintOpenGLView(TQRect(0, 0, m_canvas->width(), m_canvas->height())); + } else { + TQRect drawRect(0, m_canvasPixmap.height() + yShift, m_canvasPixmap.width(), -yShift); + + bitBlt(&m_canvasPixmap, 0, 0, &m_canvasPixmap, 0, -yShift, m_canvasPixmap.width(), m_canvasPixmap.height() + yShift); + + updateTQPaintDeviceCanvas(viewToWindow(drawRect)); + m_canvas->tqrepaint(); + } + } + if (m_oldTool) { + KisCanvasPainter gc(m_canvas); + m_oldTool->paint(gc); + } + } + + if (yShift != 0) { + // XXX do sth with the childframe or so + } + emit viewTransformationsChanged(); +} + +void KisView::setupCanvas() +{ + m_canvas = new KisCanvas(this, "kis_canvas"); + m_canvas->setFocusPolicy( TQ_StrongFocus ); + TQObject::connect(m_canvas, TQT_SIGNAL(sigGotButtonPressEvent(KisButtonPressEvent*)), TQT_TQOBJECT(this), TQT_SLOT(canvasGotButtonPressEvent(KisButtonPressEvent*))); + TQObject::connect(m_canvas, TQT_SIGNAL(sigGotButtonReleaseEvent(KisButtonReleaseEvent*)), TQT_TQOBJECT(this), TQT_SLOT(canvasGotButtonReleaseEvent(KisButtonReleaseEvent*))); + TQObject::connect(m_canvas, TQT_SIGNAL(sigGotDoubleClickEvent(KisDoubleClickEvent*)), TQT_TQOBJECT(this), TQT_SLOT(canvasGotDoubleClickEvent(KisDoubleClickEvent*))); + TQObject::connect(m_canvas, TQT_SIGNAL(sigGotMoveEvent(KisMoveEvent*)), TQT_TQOBJECT(this), TQT_SLOT(canvasGotMoveEvent(KisMoveEvent*))); + TQObject::connect(m_canvas, TQT_SIGNAL(sigGotPaintEvent(TQPaintEvent*)), TQT_TQOBJECT(this), TQT_SLOT(canvasGotPaintEvent(TQPaintEvent*))); + TQObject::connect(m_canvas, TQT_SIGNAL(sigGotEnterEvent(TQEvent*)), TQT_TQOBJECT(this), TQT_SLOT(canvasGotEnterEvent(TQEvent*))); + TQObject::connect(m_canvas, TQT_SIGNAL(sigGotLeaveEvent(TQEvent*)), TQT_TQOBJECT(this), TQT_SLOT(canvasGotLeaveEvent(TQEvent*))); + TQObject::connect(m_canvas, TQT_SIGNAL(sigGotMouseWheelEvent(TQWheelEvent*)), TQT_TQOBJECT(this), TQT_SLOT(canvasGotMouseWheelEvent(TQWheelEvent*))); + TQObject::connect(m_canvas, TQT_SIGNAL(sigGotKeyPressEvent(TQKeyEvent*)), TQT_TQOBJECT(this), TQT_SLOT(canvasGotKeyPressEvent(TQKeyEvent*))); + TQObject::connect(m_canvas, TQT_SIGNAL(sigGotKeyReleaseEvent(TQKeyEvent*)), TQT_TQOBJECT(this), TQT_SLOT(canvasGotKeyReleaseEvent(TQKeyEvent*))); + TQObject::connect(m_canvas, TQT_SIGNAL(sigGotDragEnterEvent(TQDragEnterEvent*)), TQT_TQOBJECT(this), TQT_SLOT(canvasGotDragEnterEvent(TQDragEnterEvent*))); + TQObject::connect(m_canvas, TQT_SIGNAL(sigGotDropEvent(TQDropEvent*)), TQT_TQOBJECT(this), TQT_SLOT(canvasGotDropEvent(TQDropEvent*))); +} + +void KisView::connectCurrentImg() +{ + if (m_image) { + connect(m_image, TQT_SIGNAL(sigActiveSelectionChanged(KisImageSP)), m_selectionManager, TQT_SLOT(imgSelectionChanged(KisImageSP))); + connect(m_image, TQT_SIGNAL(sigActiveSelectionChanged(KisImageSP)), TQT_TQOBJECT(this), TQT_SLOT(updateCanvas())); + connect(m_image, TQT_SIGNAL(sigColorSpaceChanged(KisColorSpace *)), TQT_TQOBJECT(this), TQT_SLOT(updateStatusBarProfileLabel())); + connect(m_image, TQT_SIGNAL(sigProfileChanged(KisProfile * )), TQT_SLOT(profileChanged(KisProfile * ))); + + connect(m_image, TQT_SIGNAL(sigLayersChanged(KisGroupLayerSP)), TQT_SLOT(layersUpdated())); + connect(m_image, TQT_SIGNAL(sigMaskInfoChanged()), TQT_SLOT(tqmaskUpdated())); + connect(m_image, TQT_SIGNAL(sigLayerAdded(KisLayerSP)), TQT_SLOT(layersUpdated())); + connect(m_image, TQT_SIGNAL(sigLayerRemoved(KisLayerSP, KisGroupLayerSP, KisLayerSP)), TQT_SLOT(layersUpdated())); + connect(m_image, TQT_SIGNAL(sigLayerMoved(KisLayerSP, KisGroupLayerSP, KisLayerSP)), TQT_SLOT(layersUpdated())); + connect(m_image, TQT_SIGNAL(sigLayerActivated(KisLayerSP)), TQT_SLOT(layersUpdated())); + connect(m_image, TQT_SIGNAL(sigLayerActivated(KisLayerSP)), TQT_SLOT(updateCanvas())); + connect(m_image, TQT_SIGNAL(sigLayerPropertiesChanged(KisLayerSP)), TQT_SLOT(layersUpdated())); + + KisConnectPartLayerVisitor v(m_image, this, true); + m_image->rootLayer()->accept(v); + connect(m_image, TQT_SIGNAL(sigLayerAdded(KisLayerSP)), + TQT_SLOT(handlePartLayerAdded(KisLayerSP))); + + tqmaskUpdated(); +#ifdef HAVE_GL + if (m_OpenGLImageContext != 0) { + connect(m_OpenGLImageContext, TQT_SIGNAL(sigImageUpdated(TQRect)), TQT_SLOT(slotOpenGLImageUpdated(TQRect))); + connect(m_OpenGLImageContext, TQT_SIGNAL(sigSizeChanged(TQ_INT32, TQ_INT32)), TQT_SLOT(slotImageSizeChanged(TQ_INT32, TQ_INT32))); + } else +#endif + { + connect(m_image, TQT_SIGNAL(sigImageUpdated(TQRect)), TQT_SLOT(imgUpdated(TQRect))); + connect(m_image, TQT_SIGNAL(sigSizeChanged(TQ_INT32, TQ_INT32)), TQT_SLOT(slotImageSizeChanged(TQ_INT32, TQ_INT32))); + } + } + + m_layerBox->setImage(m_image); + m_birdEyeBox->setImage(m_image); +} + +void KisView::disconnectCurrentImg() +{ + if (m_image) { + m_image->disconnect(this); + m_layerBox->setImage(0); + m_birdEyeBox->setImage(0); + + KisConnectPartLayerVisitor v(m_image, this, false); + m_image->rootLayer()->accept(v); + } + +#ifdef HAVE_GL + if (m_OpenGLImageContext != 0) { + m_OpenGLImageContext->disconnect(this); + } +#endif +} + +void KisView::handlePartLayerAdded(KisLayerSP layer) +{ + KisPartLayer* l = dynamic_cast<KisPartLayer*>(layer.data()); + if (!l) + return; + + connect(TQT_TQOBJECT(this), TQT_SIGNAL(childActivated(KoDocumentChild*)), + layer, TQT_SLOT(childActivated(KoDocumentChild*))); +} + +void KisView::imgUpdated(TQRect rc) +{ + updateCanvas(rc); +} + +void KisView::slotOpenGLImageUpdated(TQRect rc) +{ + paintOpenGLView(windowToView(rc)); +} + +void KisView::profileChanged(KisProfile * /*profile*/) +{ + updateStatusBarProfileLabel(); +} + +void KisView::slotImageSizeChanged(TQ_INT32 /*w*/, TQ_INT32 /*h*/) +{ + resizeEvent(0); + refreshKisCanvas(); +} + +void KisView::resizeCurrentImage(TQ_INT32 w, TQ_INT32 h, bool cropLayers) +{ + if (!currentImg()) return; + + currentImg()->resize(w, h, cropLayers); + m_doc->setModified(true); + layersUpdated(); +} + +void KisView::scaleCurrentImage(double sx, double sy, KisFilterStrategy *filterStrategy) +{ + if (!currentImg()) return; + currentImg()->scale(sx, sy, m_progress, filterStrategy); + m_doc->setModified(true); + layersUpdated(); +} + +void KisView::rotateCurrentImage(double radians) +{ + if (!currentImg()) return; + currentImg()->rotate(radians, m_progress); + m_doc->setModified(true); + layersUpdated(); +} + +void KisView::shearCurrentImage(double angleX, double angleY) +{ + if (!currentImg()) return; + currentImg()->shear(angleX, angleY, m_progress); + m_doc->setModified(true); + layersUpdated(); +} + + +TQPoint KisView::viewToWindow(const TQPoint& pt) +{ + TQPoint converted; + + converted.rx() = static_cast<int>((pt.x() + horzValue()) / zoom()); + converted.ry() = static_cast<int>((pt.y() + vertValue()) / zoom()); + + return converted; +} + +TQPoint KisView::viewToWindow(const TQPoint& pt) const +{ + TQPoint converted; + + converted.rx() = static_cast<int>((pt.x() + horzValue()) / zoom()); + converted.ry() = static_cast<int>((pt.y() + vertValue()) / zoom()); + + return converted; +} + +KisPoint KisView::viewToWindow(const KisPoint& pt) +{ + KisPoint converted; + + converted.setX((pt.x() + horzValue()) / zoom()); + converted.setY((pt.y() + vertValue()) / zoom()); + + return converted; +} + +TQRect KisView::viewToWindow(const TQRect& rc) +{ + TQRect r; + + r.setTopLeft(viewToWindow(rc.topLeft())); + r.setRight((int)(ceil((rc.right() + 1.0 + horzValue()) / zoom()) - 1)); + r.setBottom((int)(ceil((rc.bottom() + 1.0 + vertValue()) / zoom()) - 1)); + + return r; +} + +KisRect KisView::viewToWindow(const KisRect& rc) +{ + KisRect r; + KisPoint p = viewToWindow(KisPoint(rc.x(), rc.y())); + r.setX(p.x()); + r.setY(p.y()); + r.setWidth(rc.width() / zoom()); + r.setHeight(rc.height() / zoom()); + + return r; +} + +void KisView::viewToWindow(TQ_INT32 *x, TQ_INT32 *y) +{ + if (x && y) { + TQPoint p = viewToWindow(TQPoint(*x, *y)); + *x = p.x(); + *y = p.y(); + } +} + +TQPoint KisView::windowToView(const TQPoint& pt) +{ + TQPoint p; + p.setX(static_cast<int>(pt.x() * zoom() - horzValue())); + p.setY(static_cast<int>(pt.y() * zoom() - vertValue())); + + return p; +} + +TQPoint KisView::windowToView(const TQPoint& pt) const +{ + TQPoint p; + p.setX(static_cast<int>(pt.x() * zoom() - horzValue())); + p.setY(static_cast<int>(pt.y() * zoom() - vertValue())); + + return p; +} + +KisPoint KisView::windowToView(const KisPoint& pt) +{ + KisPoint p; + p.setX(pt.x() * zoom() - horzValue()); + p.setY(pt.y() * zoom() - vertValue()); + + return p; +} + +TQRect KisView::windowToView(const TQRect& rc) +{ + TQRect r; + + r.setTopLeft(windowToView(rc.topLeft())); + r.setRight((int)(ceil((rc.right() + 1.0) * zoom()) - horzValue() - 1)); + r.setBottom((int)(ceil((rc.bottom() + 1.0) * zoom()) - vertValue() - 1)); + + return r; +} + +KisRect KisView::windowToView(const KisRect& rc) +{ + KisRect r; + KisPoint p = windowToView(KisPoint(rc.x(), rc.y())); + r.setX(p.x()); + r.setY(p.y()); + r.setWidth(rc.width() * zoom()); + r.setHeight(rc.height() * zoom()); + + return r; +} + +void KisView::windowToView(TQ_INT32 *x, TQ_INT32 *y) +{ + if (x && y) { + TQPoint p = windowToView(TQPoint(*x, *y)); + *x = p.x(); + *y = p.y(); + } +} + +void KisView::guiActivateEvent(KParts::GUIActivateEvent *event) +{ + Q_ASSERT(event); + + if (event->activated()) { + + KStatusBar *sb = statusBar(); + if (sb) { + sb->show(); + } + + if (!m_guiActivateEventReceived) { + m_guiActivateEventReceived = true; + startInitialZoomTimerIfReady(); + } + } + + super::guiActivateEvent(event); +} + +bool KisView::eventFilter(TQObject *o, TQEvent *e) +{ + Q_ASSERT(o); + Q_ASSERT(e); + + switch (e->type()) { + case TQEvent::TabletMove: + case TQEvent::TabletPress: + case TQEvent::TabletRelease: + { + TQTabletEvent *te = TQT_TQTABLETEVENT(e); + KisInputDevice device; + + switch (te->device()) { + default: + case TQTabletEvent::Stylus: + case TQTabletEvent::NoDevice: + device = KisInputDevice::stylus(); + break; + case TQTabletEvent::Puck: + device = KisInputDevice::puck(); + break; + case TQTabletEvent::Eraser: + device = KisInputDevice::eraser(); + break; + } + + setInputDevice(device); + + // We ignore device change due to mouse events for a short duration + // after a tablet event, since these are almost certainly mouse events + // sent to tqreceivers that don't accept the tablet event. + m_tabletEventTimer.start(); + break; + } + case TQEvent::MouseButtonPress: + case TQEvent::MouseMove: + case TQEvent::MouseButtonRelease: + { +#ifdef EXTENDED_X11_TABLET_SUPPORT + KisInputDevice device = KisCanvasWidget::findActiveInputDevice(); + + if (device != KisInputDevice::mouse()) { + setInputDevice(device); + m_tabletEventTimer.start(); + } else +#endif + { + if (currentInputDevice() != KisInputDevice::mouse() && m_tabletEventTimer.elapsed() > MOUSE_CHANGE_EVENT_DELAY) { + setInputDevice(KisInputDevice::mouse()); + } + } + break; + } + case TQEvent::KeyPress: + case TQEvent::KeyRelease: + { + if (m_canvas->cursorIsOverCanvas()) { + m_canvas->handleKeyEvent(e); + return true; + } + break; + } +#if 0 + // This code is unnecessary now that there's an application event filter + // This eventFilter is called for all widgets already, no need to install event filters multiple times + // Even worse: with multiple views, they would all install event filters on each other's widgets, + // due to the qapp event filter triggering in all views! + case TQEvent::ChildInserted: + { + TQChildEvent *childEvent = static_cast<TQChildEvent *>(e); + TQObject *child = childEvent->child(); + if ( child->isWidgetType() ) { + + child->installEventFilter(this); + + TQObjectList *objectList = child->queryList(TQWIDGET_OBJECT_NAME_STRING); + TQObjectListIt it(*objectList); + TQObject *obj; + while ((obj = it.current()) != 0) { + obj->installEventFilter(this); + ++it; + } + delete objectList; + } + } +#endif + default: + // Ignore + break; + } + +#if 0 + if ((o == m_hRuler || o == m_vRuler) && (e->type() == TQEvent::MouseMove || e->type() == TQEvent::MouseButtonRelease)) { + TQMouseEvent *me = dynamic_cast<TQMouseEvent*>(e); + TQPoint pt = mapFromGlobal(me->globalPos()); + KisImageSP img = currentImg(); + KisGuideMgr *mgr; + + if (!img) + return super::eventFilter(o, e); + + mgr = img->guides(); + + if (e->type() == TQEvent::MouseMove && (me->state() & Qt::LeftButton)) { + bool flag = tqgeometry().tqcontains(pt); + KisGuideSP gd; + + if (m_currentGuide == 0 && flag) { + // No guide is being edited and moving mouse over the canvas. + // Create a new guide. + enterEvent(0); + eraseGuides(); + mgr->unselectAll(); + + if (o == m_vRuler) + gd = mgr->add((pt.x() - m_vRuler->width() + horzValue()) / zoom(), Qt::Vertical); + else + gd = mgr->add((pt.y() - m_hRuler->height() + vertValue()) / zoom(), Qt::Horizontal); + + m_currentGuide = gd; + mgr->select(gd); + m_lastGuidePoint = mapToScreen(pt); + } else if (m_currentGuide) { + if (flag) { + // moved an existing guide. + KisMoveEvent kme(currentInputDevice(), pt, me->globalPos(), PRESSURE_DEFAULT, 0, 0, me->state()); + canvasGotMoveEvent(&kme); + } else { + // moved a guide out of the frame, destroy it + leaveEvent(0); + eraseGuides(); + mgr->remove(m_currentGuide); + paintGuides(); + m_currentGuide = 0; + } + } + } else if (e->type() == TQEvent::MouseButtonRelease && m_currentGuide) { + eraseGuides(); + mgr->unselect(m_currentGuide); + paintGuides(); + m_currentGuide = 0; + enterEvent(0); + KisMoveEvent kme(currentInputDevice(), pt, me->globalPos(), PRESSURE_DEFAULT, 0, 0, Qt::NoButton); + canvasGotMoveEvent(&kme); + } + } +#endif + + return super::eventFilter(o, e); +} + +#if 0 +void KisView::eraseGuides() +{ + KisImageSP img = currentImg(); + + if (img) { + KisGuideMgr *mgr = img->guides(); + + if (mgr) + mgr->erase(&m_canvasPixmap, this, horzValue(), vertValue(), zoom()); + } +} + +void KisView::paintGuides() +{ + KisImageSP img = currentImg(); + + if (img) { + KisGuideMgr *mgr = img->guides(); + + if (mgr) + mgr->paint(&m_canvasPixmap, this, horzValue(), vertValue(), zoom()); + } +} + +void KisView::updateGuides() +{ + eraseGuides(); + paintGuides(); +} +#endif + +//void KisView::viewGuideLines() +//{ +//} + +TQPoint KisView::mapToScreen(const TQPoint& pt) +{ + TQPoint converted; + + converted.rx() = pt.x() + horzValue(); + converted.ry() = pt.y() + vertValue(); + return converted; +} + +void KisView::attach(KisCanvasObserver *observer) +{ + Q_ASSERT(observer); + if (observer) + m_observers.push_back(observer); +} + +void KisView::detach(KisCanvasObserver *observer) +{ + Q_ASSERT(observer); + if (observer) { + vKisCanvasObserver_it it = std::find(m_observers.begin(), m_observers.end(), observer); + + if (it != m_observers.end()) + m_observers.erase(it); + } +} + +void KisView::notifyObservers() +{ + for (vKisCanvasObserver_it it = m_observers.begin(); it != m_observers.end(); ++it) { + (*it)->update(this); + } +} + +KisImageSP KisView::currentImg() const +{ + return m_image; +} + +void KisView::setCurrentImage(KisImageSP image) +{ + if(!image) return; + + disconnectCurrentImg(); + m_image = image; + + KisConfig cfg; + +#ifdef HAVE_GL + if (cfg.useOpenGL()) { + m_OpenGLImageContext = KisOpenGLImageContext::getImageContext(image, monitorProfile()); + m_canvas->createOpenGLCanvas(m_OpenGLImageContext->sharedContextWidget()); + } +#endif + connectCurrentImg(); + m_layerBox->setImage(currentImg()); + + zoomAroundPoint(0, 0, 1.0); + + if (!currentImg()) + layersUpdated(); + + imgUpdateGUI(); + + image->blockSignals(false); +} + +KisColor KisView::bgColor() const +{ + return m_bg; +} + +KisColor KisView::fgColor() const +{ + return m_fg; +} + +KisBrush *KisView::currentBrush() const +{ + return m_brush; +} + +KisPattern *KisView::currentPattern() const +{ + return m_pattern; +} + +KisGradient *KisView::currentGradient() const +{ + return m_gradient; +} + +KisID KisView::currentPaintop() const +{ + return m_paintop; +} + +const KisPaintOpSettings *KisView::currentPaintopSettings() const +{ + return m_paintopSettings; +} + +double KisView::zoomFactor() const +{ + return zoom(); +} + +KisUndoAdapter *KisView::undoAdapter() const +{ + return m_adapter; +} + +KisCanvasController *KisView::canvasController() const +{ + return const_cast<KisCanvasController*>(static_cast<const KisCanvasController*>(this)); +} + +KisToolControllerInterface *KisView::toolController() const +{ + return const_cast<KisToolControllerInterface*>(static_cast<const KisToolControllerInterface*>(m_toolManager)); +} + +KisDoc *KisView::document() const +{ + return m_doc; +} + +KisProgressDisplayInterface *KisView::progressDisplay() const +{ + return m_progress; +} + +TQCursor KisView::setCanvasCursor(const TQCursor & cursor) +{ + TQCursor oldCursor = m_canvas->cursor(); + TQCursor newCursor; + + KisConfig cfg; + + switch (cfg.cursorStyle()) { + case CURSOR_STYLE_TOOLICON: + newCursor = cursor; + break; + case CURSOR_STYLE_CROSSHAIR: + newCursor = KisCursor::crossCursor(); + break; + case CURSOR_STYLE_POINTER: + newCursor = KisCursor::arrowCursor(); + break; + case CURSOR_STYLE_OUTLINE: + newCursor = cursor; + break; + default: + newCursor = cursor; + } + + m_canvas->setCursor(newCursor); + return oldCursor; +} + +float KisView::HDRExposure() const +{ + return m_HDRExposure; +} + +void KisView::setHDRExposure(float exposure) +{ + if (exposure != m_HDRExposure) { + m_HDRExposure = exposure; + notifyObservers(); + updateCanvas(); + } +} + +void KisView::createDockers() +{ + + m_birdEyeBox = new KisBirdEyeBox(this); + m_birdEyeBox->setCaption(i18n("Overview")); + m_paletteManager->addWidget( m_birdEyeBox, "birdeyebox", chalk::CONTROL_PALETTE); + + m_hsvwidget = new KoHSVWidget(this, "hsv"); + m_hsvwidget->setCaption(i18n("HSV")); + + connect(m_hsvwidget, TQT_SIGNAL(sigFgColorChanged(const TQColor &)), TQT_TQOBJECT(this), TQT_SLOT(slotSetFGQColor(const TQColor &))); + connect(m_hsvwidget, TQT_SIGNAL(sigBgColorChanged(const TQColor &)), TQT_TQOBJECT(this), TQT_SLOT(slotSetBGQColor(const TQColor &))); + connect(TQT_TQOBJECT(this), TQT_SIGNAL(sigFGQColorChanged(const TQColor &)), m_hsvwidget, TQT_SLOT(setFgColor(const TQColor &))); + connect(TQT_TQOBJECT(this), TQT_SIGNAL(sigBGQColorChanged(const TQColor &)), m_hsvwidget, TQT_SLOT(setBgColor(const TQColor &))); + m_paletteManager->addWidget( m_hsvwidget, "hsvwidget", chalk::COLORBOX, 0, PALETTE_DOCKER, true); + + m_rgbwidget = new KoRGBWidget(this, "rgb"); + m_rgbwidget->setCaption(i18n("RGB")); + connect(m_rgbwidget, TQT_SIGNAL(sigFgColorChanged(const TQColor &)), TQT_TQOBJECT(this), TQT_SLOT(slotSetFGQColor(const TQColor &))); + connect(m_rgbwidget, TQT_SIGNAL(sigBgColorChanged(const TQColor &)), TQT_TQOBJECT(this), TQT_SLOT(slotSetBGQColor(const TQColor &))); + connect(TQT_TQOBJECT(this), TQT_SIGNAL(sigFGQColorChanged(const TQColor &)), m_rgbwidget, TQT_SLOT(setFgColor(const TQColor &))); + connect(TQT_TQOBJECT(this), TQT_SIGNAL(sigBGQColorChanged(const TQColor &)), m_rgbwidget, TQT_SLOT(setBgColor(const TQColor &))); + m_paletteManager->addWidget( m_rgbwidget, "rgbwidget", chalk::COLORBOX); + + m_graywidget = new KoGrayWidget(this, "gray"); + m_graywidget->setCaption(i18n("Gray")); + connect(m_graywidget, TQT_SIGNAL(sigFgColorChanged(const TQColor &)), TQT_TQOBJECT(this), TQT_SLOT(slotSetFGQColor(const TQColor &))); + connect(m_graywidget, TQT_SIGNAL(sigBgColorChanged(const TQColor &)), TQT_TQOBJECT(this), TQT_SLOT(slotSetBGQColor(const TQColor &))); + connect(TQT_TQOBJECT(this), TQT_SIGNAL(sigFGQColorChanged(const TQColor &)), m_graywidget, TQT_SLOT(setFgColor(const TQColor &))); + connect(TQT_TQOBJECT(this), TQT_SIGNAL(sigBGQColorChanged(const TQColor &)), m_graywidget, TQT_SLOT(setBgColor(const TQColor &))); + m_paletteManager->addWidget( m_graywidget, "graywidget", chalk::COLORBOX); + + //make sure the color chooser get right default values + emit sigFGQColorChanged(m_fg.toTQColor()); + emit sigBGQColorChanged(m_bg.toTQColor()); + + m_palettewidget = new KisPaletteWidget(this); + m_palettewidget->setCaption(i18n("Palettes")); + connect(m_palettewidget, TQT_SIGNAL(colorSelected(const TQColor &)), + TQT_TQOBJECT(this), TQT_SLOT(slotSetFGQColor(const TQColor &))); + // No BGColor or reverse slotFGChanged->palette connections, since that's not useful here + + KisResourceServerBase* rServer; + rServer = KisResourceServerRegistry::instance()->get("PaletteServer"); + TQValueList<KisResource*> resources = rServer->resources(); + TQValueList<KisResource*>::iterator it; + for ( it = resources.begin(); it != resources.end(); ++it ) { + m_palettewidget->slotAddPalette( *it ); + } + connect(m_palettewidget, TQT_SIGNAL(colorSelected(const KisColor &)), TQT_TQOBJECT(this), TQT_SLOT(slotSetFGColor(const KisColor &))); + m_paletteManager->addWidget( m_palettewidget, "palettewidget", chalk::COLORBOX, 10, PALETTE_DOCKER, true); +} + +TQPoint KisView::applyViewTransformations(const TQPoint& p) const { + TQPoint point(windowToView(p)); + + if (m_hRuler->isShown()) + point.ry() += m_hRuler->height(); + if (m_vRuler -> isShown()) + point.rx() += m_vRuler->width(); + + return point; +} + +TQPoint KisView::reverseViewTransformations(const TQPoint& p) const { + // Since we now zoom ourselves, the only thing super::~ does is nothing anymore. + // Hence, zoom ourselves, like super would + // viewToWindow doesn't take the rulers into account, do that ourselves + TQPoint point(p); + if (m_hRuler -> isShown()) + point.ry() -= m_hRuler -> height(); + if (m_vRuler -> isShown()) + point.rx() -= m_vRuler -> width(); + + return viewToWindow(point); +} + +void KisView::canvasAddChild(KoViewChild *child) { + super::canvasAddChild(child); + connect(TQT_TQOBJECT(this), TQT_SIGNAL(viewTransformationsChanged()), child, TQT_SLOT(reposition())); + m_vScroll->raise(); + m_hScroll->raise(); + m_vScroll->raise(); + m_hRuler->raise(); + m_vRuler->raise(); +} + +void KisView::slotLoadingFinished() +{ + // Set the current image for real now everything is ready to go. + setCurrentImage(document()->currentImage()); + m_paletteManager->showWidget( "layerbox" ); + m_canvas->show(); + disconnect(document(), TQT_SIGNAL(loadingFinished()), TQT_TQOBJECT(this), TQT_SLOT(slotLoadingFinished())); + + m_imageLoaded = true; + startInitialZoomTimerIfReady(); +} + +void KisView::startInitialZoomTimerIfReady() +{ + if (m_imageLoaded && m_showEventReceived && m_guiActivateEventReceived) { + m_initialZoomTimer.start(250, true); + } +} + +void KisView::slotInitialZoomTimeout() +{ + Q_ASSERT(!m_paintViewEnabled); + + m_paintViewEnabled = true; + setInitialZoomLevel(); +} + + +void KisView::slotCreateMask() { + KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(currentImg()->activeLayer().data()); + if (!layer) + return; + + KNamedCommand *cmd = layer->createMaskCommand(); + cmd->execute(); + if (undoAdapter() && undoAdapter()->undo()) { + undoAdapter()->addCommand(cmd); + } +} + +void KisView::slotMaskFromSelection() { + KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(currentImg()->activeLayer().data()); + if (!layer) + return; + + KNamedCommand *cmd = layer->tqmaskFromSelectionCommand(); + cmd->execute(); + if (undoAdapter() && undoAdapter()->undo()) { + undoAdapter()->addCommand(cmd); + } +} + +void KisView::slotMaskToSelection() { + KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(currentImg()->activeLayer().data()); + if (!layer) + return; + + KNamedCommand *cmd = layer->tqmaskToSelectionCommand(); + cmd->execute(); + if (undoAdapter() && undoAdapter()->undo()) { + undoAdapter()->addCommand(cmd); + } +} + +void KisView::slotApplyMask() { + KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(currentImg()->activeLayer().data()); + if (!layer) + return; + + KNamedCommand *cmd = layer->applyMaskCommand(); + cmd->execute(); + if (undoAdapter() && undoAdapter()->undo()) { + undoAdapter()->addCommand(cmd); + } +} + +void KisView::slotRemoveMask() { + KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(currentImg()->activeLayer().data()); + if (!layer) + return; + + KNamedCommand *cmd = layer->removeMaskCommand(); + cmd->execute(); + if (undoAdapter() && undoAdapter()->undo()) { + undoAdapter()->addCommand(cmd); + } +} + +void KisView::slotEditMask() { + KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(currentImg()->activeLayer().data()); + if (!layer) + return; + + layer->setEditMask(m_editMask->isChecked()); +} + +void KisView::slotShowMask() { + KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(currentImg()->activeLayer().data()); + if (!layer) + return; + + layer->setRenderMask(m_showMask->isChecked()); +} + +void KisView::tqmaskUpdated() { + KisPaintLayer* layer = dynamic_cast<KisPaintLayer*>(currentImg()->activeLayer().data()); + if (!layer) { + m_createMask->setEnabled(false); + m_applyMask->setEnabled(false); + m_removeMask->setEnabled(false); + m_editMask->setEnabled(false); + m_showMask->setEnabled(false); + return; + } + m_createMask->setEnabled(!layer->hasMask()); + m_tqmaskFromSelection->setEnabled(true); // Perhaps also update this to false when no selection? + m_tqmaskToSelection->setEnabled(layer->hasMask()); + m_applyMask->setEnabled(layer->hasMask()); + m_removeMask->setEnabled(layer->hasMask()); + + m_editMask->setEnabled(layer->hasMask()); + m_editMask->setChecked(layer->editMask()); + m_showMask->setEnabled(layer->hasMask()); + m_showMask->setChecked(layer->renderMask()); +} + +#include "kis_view.moc" + diff --git a/chalk/ui/kis_view.h b/chalk/ui/kis_view.h new file mode 100644 index 00000000..1f197f87 --- /dev/null +++ b/chalk/ui/kis_view.h @@ -0,0 +1,664 @@ +/* + * Copyright (c) 1999 Matthias Elter <me@kde.org> + * 1999 Michael Koch <koch@kde.org> + * 1999 Carsten Pfeiffer <pfeiffer@kde.org> + * 2002 Patrick Julien <freak@codepimps.org> + * 2004 Clarence Dang <dang@kde.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_VIEW_H_ +#define KIS_VIEW_H_ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <list> + +#include <tqdatetime.h> +#include <tqpixmap.h> +#include <tqstringlist.h> +#include <tqtimer.h> + +#include <ksqueezedtextlabel.h> +#include <kdebug.h> +#include <kxmlguibuilder.h> +#include <kxmlguiclient.h> +#include <KoView.h> + +#include "kis_canvas_controller.h" +#include "kis_canvas_subject.h" +#include "kis_global.h" +// #include "kis_debug_areas.h" +#include "kis_types.h" +#include "kis_profile.h" +#include "kis_opengl_image_context.h" +#include "kis_id.h" +#include "koffice_export.h" +#include "kis_color.h" +#include "kis_input_device.h" + +class TQButton; +class TQLabel; +class TQPaintEvent; +class TQScrollBar; +class TQWidget; +class TQPopup; +class TQPopupMenu; + +class DCOPObject; +class KAction; +class KActionMenu; +class KPrinter; +class KToggleAction; +class KToolBar; + +class KoPartSelectAction; +class KoDocumentEntry; +class KoIconItem; +class KoTabBar; +class KoPaletteManager; +class KoGrayWidget; +class KoHSVWidget; +class KoRGBWidget; + +class KisBirdEyeBox; +class KisBrush; +class KisButtonPressEvent; +class KisButtonReleaseEvent; +class KisCanvas; +class KisCanvasObserver; +class KisCompositeOp; +class KisControlFrame; +class KisDoc; +class KisDoubleClickEvent; +class KisFilterManager; +class KisFilterStrategy; +class KisGradient; +class KisGridManager; +class KisPerspectiveGridManager; +class KisLabelProgress; +class KisLayerBox; +class KisMoveEvent; +class KisPaletteWidget; +class KisPattern; +class KisPoint; +class KisRect; +class KisResource; +class KisResourceMediator; +class KisRuler; +class KisSelectionManager; +class KoToolBox; +class KisToolControllerInterface; +class KisToolManager; +class KisUndoAdapter; +class KisFilterConfiguration; +class KisPartLayerHandler; +class KisPaintOpSettings; + +class KRITA_EXPORT KisView + : public KoView, + public KisCanvasSubject, + public KXMLGUIBuilder, + private KisCanvasController +{ + + Q_OBJECT + TQ_OBJECT + + typedef KoView super; + + typedef std::list<KisCanvasObserver*> vKisCanvasObserver; + typedef vKisCanvasObserver::iterator vKisCanvasObserver_it; + typedef vKisCanvasObserver::const_iterator vKisCanvasObserver_cit; + +public: + KisView(KisDoc *doc, KisUndoAdapter *adapter, TQWidget *tqparent = 0, const char *name = 0); + virtual ~KisView(); + +public: // KXMLGUIBuilder implementation + + virtual TQWidget *createContainer( TQWidget *tqparent, int index, const TQDomElement &element, int &id ); + virtual void removeContainer( TQWidget *container, TQWidget *tqparent, TQDomElement &element, int id ); + +public: // KoView implementation + virtual bool eventFilter(TQObject *o, TQEvent *e); + + virtual DCOPObject* dcopObject(); + + virtual void print(KPrinter &printer); + virtual void setupPrinter(KPrinter &printer); + + virtual void updateReadWrite(bool readwrite); + virtual void guiActivateEvent(KParts::GUIActivateEvent *event); + + virtual int leftBorder() const; + virtual int rightBorder() const; + virtual int topBorder() const; + virtual int bottomBorder() const; + + TQ_INT32 docWidth() const; + TQ_INT32 docHeight() const; + + void updateStatusBarSelectionLabel(); + + virtual TQPoint applyViewTransformations(const TQPoint& p) const; + virtual TQPoint reverseViewTransformations( const TQPoint& p) const; + virtual void canvasAddChild(KoViewChild *child); + +signals: + + void brushChanged(KisBrush * brush); + void gradientChanged(KisGradient * gradient); + void patternChanged(KisPattern * pattern); + void paintopChanged(KisID paintop, const KisPaintOpSettings *paintopSettings); + /** + * Indicates when the current layer changed so that the current colorspace could have + * changed. + **/ + void currentColorSpaceChanged(KisColorSpace* cs); + void cursorPosition(TQ_INT32 xpos, TQ_INT32 ypos); + + void sigFGQColorChanged(const TQColor &); + void sigBGQColorChanged(const TQColor &); + + void sigInputDeviceChanged(const KisInputDevice& inputDevice); + + /* + * Emitted whenever the zoom or scroll values change. + */ + void viewTransformationsChanged(); + +public slots: + + void slotSetFGColor(const KisColor& c); + void slotSetBGColor(const KisColor& c); + + void rotateLayer180(); + void rotateLayerLeft90(); + void rotateLayerRight90(); + void mirrorLayerX(); + void mirrorLayerY(); + void scaleLayer(double sx, double sy, KisFilterStrategy *filterStrategy); + void rotateLayer(double radians); + void shearLayer(double angleX, double angleY); + + void slotCreateMask(); + void slotMaskFromSelection(); + void slotMaskToSelection(); + void slotApplyMask(); + void slotRemoveMask(); + void slotEditMask(); + void slotShowMask(); + + void brushActivated(KisResource *brush); + void patternActivated(KisResource *pattern); + void gradientActivated(KisResource *gradient); + void paintopActivated(const KisID & paintop, const KisPaintOpSettings *paintopSettings); + + +public: + virtual void mouseMoveEvent(TQMouseEvent *e); + + void resizeCurrentImage(TQ_INT32 w, TQ_INT32 h, bool cropLayers = false); + void scaleCurrentImage(double sx, double sy, KisFilterStrategy *filterStrategy); + void rotateCurrentImage(double radians); + void shearCurrentImage(double angleX, double angleY); + + void insertPart(const TQRect& viewRect, const KoDocumentEntry& entry, + KisGroupLayerSP tqparent, KisLayerSP above); + + /** + * Import an image as a layer. If there is more than + * one layer in the image, import all of them as separate + * layers. + * + * @param url the url to the image file + * @return the number of layers added + */ + TQ_INT32 importImage(const KURL& url = KURL()); +protected: + + virtual void resizeEvent(TQResizeEvent*); // From TQWidget + virtual void styleChange(TQStyle& oldStyle); // From TQWidget + virtual void paletteChange(const TQPalette& oldPalette); // From TQWidget + virtual void showEvent(TQShowEvent *); + +protected slots: + virtual void slotChildActivated(bool a); // from KoView + +// -------------------------------------------------------------------------// +// KisCanvasSubject implementation +// -------------------------------------------------------------------------// +public: + + KisCanvasSubject * canvasSubject() { return this; }; + +private: + + virtual KisImageSP currentImg() const; + + virtual void attach(KisCanvasObserver *observer); + virtual void detach(KisCanvasObserver *observer); + virtual void notifyObservers(); + + virtual KisColor bgColor() const; + virtual void setBGColor(const KisColor& c); + + virtual KisColor fgColor() const; + virtual void setFGColor(const KisColor& c); + + float HDRExposure() const; + void setHDRExposure(float exposure); + + virtual KisBrush *currentBrush() const; + virtual KisPattern *currentPattern() const; + virtual KisGradient *currentGradient() const; + virtual KisID currentPaintop() const; + virtual const KisPaintOpSettings *currentPaintopSettings() const; + + virtual double zoomFactor() const; + + virtual KisUndoAdapter *undoAdapter() const; + + virtual KisCanvasController *canvasController() const; + virtual KisToolControllerInterface *toolController() const; + + virtual KisProgressDisplayInterface *progressDisplay() const; + + virtual KisDoc * document() const; + + inline KisGridManager * gridManager() { return m_gridManager; } + inline KisPerspectiveGridManager* perspectiveGridManager() { return m_perspectiveGridManager; } + + inline KisSelectionManager * selectionManager() { return m_selectionManager; } + + KoPaletteManager * paletteManager(); + + KisProfile * monitorProfile(); + + +// -------------------------------------------------------------------------// +// KisCanvasController implementation +// -------------------------------------------------------------------------// + +public: + + KisCanvasController * getCanvasController() { return this; }; + + +private slots: + virtual void updateCanvas(); + + void updateStatusBarZoomLabel(); + void updateStatusBarProfileLabel(); + +private: + virtual KisCanvas *kiscanvas() const; + + virtual TQ_INT32 horzValue() const; + virtual TQ_INT32 vertValue() const; + + virtual void scrollTo(TQ_INT32 x, TQ_INT32 y); + + virtual void updateCanvas(TQ_INT32 x, TQ_INT32 y, TQ_INT32 w, TQ_INT32 h); + virtual void updateCanvas(const TQRect& imageRect); + + virtual void zoomIn(); + virtual void zoomIn(TQ_INT32 x, TQ_INT32 y); + + virtual void zoomOut(); + virtual void zoomOut(TQ_INT32 x, TQ_INT32 y); + + virtual void zoomTo(TQ_INT32 x, TQ_INT32 y, TQ_INT32 w, TQ_INT32 h); + virtual void zoomTo(const TQRect& r); + virtual void zoomTo(const KisRect& r); + virtual void zoomAroundPoint(double x, double y, double zf); + + virtual TQPoint viewToWindow(const TQPoint& pt); + virtual TQPoint viewToWindow(const TQPoint& pt) const; + virtual KisPoint viewToWindow(const KisPoint& pt); + virtual TQRect viewToWindow(const TQRect& rc); + virtual KisRect viewToWindow(const KisRect& rc); + virtual void viewToWindow(TQ_INT32 *x, TQ_INT32 *y); + + virtual TQPoint windowToView(const TQPoint& pt); + virtual TQPoint windowToView(const TQPoint& pt) const; + virtual KisPoint windowToView(const KisPoint& pt); + virtual TQRect windowToView(const TQRect& rc); + virtual KisRect windowToView(const KisRect& rc); + virtual void windowToView(TQ_INT32 *x, TQ_INT32 *y); + + virtual TQCursor setCanvasCursor(const TQCursor & cursor); + + void setInputDevice(KisInputDevice inputDevice); + KisInputDevice currentInputDevice() const; + +// -------------------------------------------------------------------------// +// KisView internals +// -------------------------------------------------------------------------// + +private: + + void connectCurrentImg(); + void disconnectCurrentImg(); +// void eraseGuides(); +// void paintGuides(); +// void updateGuides(); +// void viewGuideLines(); + + void imgUpdateGUI(); + + void layerUpdateGUI(bool enable); + void createLayerBox(); + void createDockers(); + + void paintToolOverlay(const TQRegion& region); + + void paintTQPaintDeviceView(const TQRegion& canvasRegion); + void paintOpenGLView(const TQRect& canvasRect); + + void updateTQPaintDeviceCanvas(const TQRect& imageRect); + void updateOpenGLCanvas(const TQRect& imageRect); + + /** + * Update the whole of the KisCanvas, including areas outside the image. + */ + void refreshKisCanvas(); + + void selectionDisplayToggled(bool displaySelection); + + bool activeLayerHasSelection(); + + /** + * Reset the monitor profile to the new settings. + */ + void resetMonitorProfile(); + + void setupActions(); + void setupCanvas(); + void setupRulers(); + void setupScrollBars(); + void setupStatusBar(); + + + KisFilterManager * filterManager() { return m_filterManager; } + void setCurrentImage(KisImageSP image); + + /** + * Returns the next zoom level when zooming in from the current level. + */ + double nextZoomInLevel() const; + + /** + * Returns the next zoom level when zooming out from the current level. + */ + double nextZoomOutLevel() const; + + /** + * Returns the next zoom level when zooming out from the given level. + */ + double nextZoomOutLevel(double zoomLevel) const; + + /** + * Returns the zoom level that fits the image to the canvas. + */ + double fitToCanvasZoomLevel() const; + + /** + * Set the zoom level on first creating the view. + */ + void setInitialZoomLevel(); + + void startInitialZoomTimerIfReady(); + +private slots: + void layersUpdated(); // Used in the channel separation to notify the view that we have added a few layers. + void tqmaskUpdated(); // To update the enabled or disabled status of the tqmask entries + + void slotSetFGQColor(const TQColor & c); + void slotSetBGQColor(const TQColor & c); + + void imgUpdated(TQRect rc); + void slotOpenGLImageUpdated(TQRect rc); + + void imgResizeToActiveLayer(); + + void canvasGotMoveEvent(KisMoveEvent *e); + void canvasGotButtonPressEvent(KisButtonPressEvent *e); + void canvasGotButtonReleaseEvent(KisButtonReleaseEvent *e); + void canvasGotDoubleClickEvent(KisDoubleClickEvent *e); + void canvasGotPaintEvent(TQPaintEvent *e); + void canvasGotEnterEvent(TQEvent *e); + void canvasGotLeaveEvent(TQEvent *e); + void canvasGotMouseWheelEvent(TQWheelEvent *e); + void canvasGotKeyPressEvent(TQKeyEvent*); + void canvasGotKeyReleaseEvent(TQKeyEvent*); + void canvasGotDragEnterEvent(TQDragEnterEvent*); + void canvasGotDropEvent(TQDropEvent*); + + void reconnectAfterPartInsert(); + + TQPoint mapToScreen(const TQPoint& pt); + void slotImageProperties(); + + void layerCompositeOp(const KisCompositeOp& compositeOp); + void layerOpacity(int opacity, bool dontundo); + void layerOpacityFinishedChanging(int previous, int opacity); + + void layerToggleVisible(); + void layerToggleLocked(); + void actLayerVisChanged(int show); + void layerProperties(); + void showLayerProperties(KisLayerSP layer); + void layerAdd(); + void addLayer(KisGroupLayerSP tqparent, KisLayerSP above); + void addGroupLayer(KisGroupLayerSP tqparent, KisLayerSP above); + void addPartLayer(); + void addPartLayer(KisGroupLayerSP tqparent, KisLayerSP above, const KoDocumentEntry& entry); + void addAdjustmentLayer(); + void addAdjustmentLayer(KisGroupLayerSP tqparent, KisLayerSP above); + void addAdjustmentLayer(KisGroupLayerSP tqparent, KisLayerSP above, const TQString & name, KisFilterConfiguration * filter, KisSelectionSP selection = 0); + void layerRemove(); + void layerDuplicate(); + void layerRaise(); + void layerLower(); + void layerFront(); + void layerBack(); + void flattenImage(); + void mergeLayer(); + void saveLayerAsImage(); + + void slotUpdateFullScreen(bool toggle); + void showRuler(); + + void slotZoomIn(); + void slotZoomOut(); + void slotActualPixels(); + void slotActualSize(); + void slotFitToCanvas(); + + void slotImageSizeChanged(TQ_INT32 w, TQ_INT32 h); + + void scrollH(int value); + void scrollV(int value); + + void slotInsertImageAsLayer(); + void profileChanged(KisProfile * profile); + + void slotAddPalette(); + void slotEditPalette(); + + void preferences(); + + void slotAutoScroll(const TQPoint &p); + + void handlePartLayerAdded(KisLayerSP layer); + + /// Is called when the file is loaded + void slotLoadingFinished(); + + void slotInitialZoomTimeout(); + +private: + + bool m_panning; + + KisTool * m_oldTool; + + KisDoc *m_doc; + KisCanvas *m_canvas; + KisPartLayerHandler* m_partHandler; + + KisGridManager * m_gridManager; + KisPerspectiveGridManager * m_perspectiveGridManager; + KisSelectionManager * m_selectionManager; + KisFilterManager * m_filterManager; + KoPaletteManager * m_paletteManager; + KisToolManager * m_toolManager; + bool m_actLayerVis; + + // Fringe benefits + KisRuler *m_hRuler; + KisRuler *m_vRuler; + TQ_INT32 m_rulerThickness; + TQ_INT32 m_vScrollBarExtent; + TQ_INT32 m_hScrollBarExtent; + + // Actions + KAction *m_imgFlatten; + KAction *m_imgMergeLayer; + KAction *m_imgRename; + KAction *m_imgResizeToLayer; + KAction *m_imgScan; + + KoPartSelectAction * m_actionPartLayer; + KAction * m_actionAdjustmentLayer; + KAction *m_layerAdd; + KAction *m_layerBottom; + KAction *m_layerDup; + KToggleAction *m_layerHide; + KAction *m_layerLower; + KAction *m_layerProperties; + KAction *m_layerRaise; + KAction *m_layerRm; + KAction *m_layerSaveAs; + KAction *m_layerTop; + + KAction *m_createMask; + KAction *m_tqmaskFromSelection; + KAction *m_tqmaskToSelection; + KAction *m_applyMask; + KAction *m_removeMask; + KToggleAction *m_editMask; + KToggleAction *m_showMask; + + KAction *m_zoomIn; + KAction *m_zoomOut; + KAction *m_actualPixels; + KAction *m_actualSize; + KAction *m_fitToCanvas; + + KAction *m_fullScreen; + KAction *m_imgProperties; + + KToggleAction *m_RulerAction; + KToggleAction *m_guideAction; + + DCOPObject *m_dcop; + + // Widgets + TQScrollBar *m_hScroll; // XXX: the sizing of the scrollthumbs + TQScrollBar *m_vScroll; // is not right yet. + int m_scrollX; + int m_scrollY; + int m_canvasXOffset; + int m_canvasYOffset; + + bool m_paintViewEnabled; + bool m_guiActivateEventReceived; + bool m_showEventReceived; + bool m_imageLoaded; + + TQTimer m_initialZoomTimer; + + +// KisGuideSP m_currentGuide; +// TQPoint m_lastGuidePoint; + KisUndoAdapter *m_adapter; + vKisCanvasObserver m_observers; + TQLabel *m_statusBarZoomLabel; + KSqueezedTextLabel *m_statusBarSelectionLabel; + KSqueezedTextLabel *m_statusBarProfileLabel; + KisLabelProgress *m_progress; + + + KisLayerBox *m_layerBox; + KoToolBox * m_toolBox; + KisControlFrame * m_brushesAndStuffToolBar; + + // Current colours, brushes, patterns etc. + + KisColor m_fg; + KisColor m_bg; + + KisBrush *m_brush; + KisPattern *m_pattern; + KisGradient *m_gradient; + + KisID m_paintop; + const KisPaintOpSettings *m_paintopSettings; + + TQTime m_tabletEventTimer; + TQTabletEvent::TabletDevice m_lastTabletEventDevice; + + TQPixmap m_canvasPixmap; + bool m_toolIsPainting; + +#ifdef HAVE_GL + // OpenGL context for the current image, containing textures + // shared between multiple views. + KisOpenGLImageContextSP m_OpenGLImageContext; +#endif + + // Monitorprofile for this view + KisProfile * m_monitorProfile; + + float m_HDRExposure; + + // Currently active input device (mouse, stylus, eraser...) + KisInputDevice m_inputDevice; + + KisBirdEyeBox * m_birdEyeBox; + KoHSVWidget *m_hsvwidget; + KoRGBWidget *m_rgbwidget; + KoGrayWidget *m_graywidget; + KisPaletteWidget *m_palettewidget; + KisID m_currentColorChooserDisplay; + +private: + KisImageSP m_image; + +protected: + + friend class KisSelectionManager; + friend class KisFilterManager; + friend class KisGridManager; + friend class KisPerspectiveGridManager; +}; + +#endif // KIS_VIEW_H_ diff --git a/chalk/ui/kis_view_iface.cc b/chalk/ui/kis_view_iface.cc new file mode 100644 index 00000000..7de36c48 --- /dev/null +++ b/chalk/ui/kis_view_iface.cc @@ -0,0 +1,98 @@ +/* + * This file is part of the KDE project + * + * Copyright (C) 2002 Laurent Montel <lmontel@mandrakesoft.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "kis_view_iface.h" + +#include "kis_view.h" + +#include <dcopclient.h> + +KisViewIface::KisViewIface( KisView *view_ ) + : KoViewIface( view_ ) +{ + m_view = view_; +} + +void KisViewIface::copy() +{ +// m_view->copy(); +} + +void KisViewIface::cut() +{ +// m_view->cut(); +} + +void KisViewIface::removeSelection() +{ +// m_view->removeSelection(); +} + +void KisViewIface::paste() +{ +// m_view->paste(); +} + +void KisViewIface::copySelectionToNewLayer() +{ +// m_view->copySelectionToNewLayer(); +} + +void KisViewIface::selectAll() +{ +// m_view->selectAll(); +} + +void KisViewIface::unSelectAll() +{ +// m_view->unSelectAll(); +} + + + +void KisViewIface::slotImportImage() +{ +} + + +void KisViewIface::rotateLayer180() +{ + m_view->rotateLayer180(); +} + +void KisViewIface::rotateLayerLeft90() +{ + m_view->rotateLayerLeft90(); +} + +void KisViewIface::rotateLayerRight90() +{ + m_view->rotateLayerRight90(); +} + +void KisViewIface::mirrorLayerX() +{ + m_view->mirrorLayerX(); +} + +void KisViewIface::mirrorLayerY() +{ + m_view->mirrorLayerY(); +} diff --git a/chalk/ui/kis_view_iface.h b/chalk/ui/kis_view_iface.h new file mode 100644 index 00000000..34701c4c --- /dev/null +++ b/chalk/ui/kis_view_iface.h @@ -0,0 +1,58 @@ +/* This file is part of the KDE project + * Copyright (C) 2002 Laurent Montel <lmontel@mandrakesoft.com> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef KRAYON_VIEW_IFACE_H +#define KRAYON_VIEW_IFACE_H + +#include <KoViewIface.h> + +#include <tqstring.h> + +class KisView; + +/** + * This is the definition of the interface Chalk presents to + * dcop. + */ +class KisViewIface : public KoViewIface +{ + K_DCOP +public: + KisViewIface( KisView *view_ ); +k_dcop: + void copy(); + void cut(); + void removeSelection(); + void paste(); + void copySelectionToNewLayer(); + void selectAll(); + void unSelectAll(); + + void slotImportImage(); + + void rotateLayer180(); + void rotateLayerLeft90(); + void rotateLayerRight90(); + void mirrorLayerX(); + void mirrorLayerY(); + +private: + KisView *m_view; +}; + +#endif diff --git a/chalk/ui/kobirdeyepanel.cpp b/chalk/ui/kobirdeyepanel.cpp new file mode 100644 index 00000000..0cd835b1 --- /dev/null +++ b/chalk/ui/kobirdeyepanel.cpp @@ -0,0 +1,619 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include <tqpixmap.h> +#include <tqimage.h> +#include <tqlayout.h> +#include <tqpainter.h> +#include <tqframe.h> +#include <tqlabel.h> +#include <tqtoolbutton.h> +#include <tqslider.h> +#include <tqcursor.h> + +#include <kdebug.h> +#include <kglobalsettings.h> +#include <kaction.h> +#include <ktoolbar.h> +#include <knuminput.h> +#include <klocale.h> + +#include <KoDocument.h> + +#include "wdgbirdeye.h" +#include "kobirdeyepanel.h" +#include "kis_int_spinbox.h" + +KoCanvasAdapter::KoCanvasAdapter() {} +KoCanvasAdapter::~KoCanvasAdapter() {} + +KoZoomAdapter::KoZoomAdapter() {} +KoZoomAdapter::~KoZoomAdapter() {} + +KoThumbnailAdapter::KoThumbnailAdapter() {} +KoThumbnailAdapter::~KoThumbnailAdapter() {} + +KoBirdEyePanel::KoBirdEyePanel( KoZoomAdapter * zoomListener, + KoThumbnailAdapter * thumbnailProvider, + KoCanvasAdapter * canvas, + TQWidget * tqparent, + const char * name, + WFlags f) + : TQWidget(tqparent, name, f) + , m_zoomListener(zoomListener) + , m_thumbnailProvider(thumbnailProvider) + , m_canvas(canvas) + , m_dragging(false) +{ + TQHBoxLayout * l = new TQHBoxLayout(this); + m_page = new WdgBirdEye(this); + m_page->zoom->setRange((int) (TQMAX(1, 100 * zoomListener->getMinZoom())), (int) (100 * zoomListener->getMaxZoom())); + m_page->zoom->setValue(100); + m_page->zoom->setSuffix("%"); + + m_page->toolbar->setIconSize(16); + m_page->view->installEventFilter(this); + m_page->view->setBackgroundMode(TQt::NoBackground); + + m_zoomIn = new KAction( i18n("Zoom In"), "birdeye_zoom_plus", 0, TQT_TQOBJECT(this), TQT_SLOT(zoomPlus()), TQT_TQOBJECT(this), "zoomIn" ); + m_zoomOut = new KAction( i18n("Zoom Out"), "birdeye_zoom_minus", 0, TQT_TQOBJECT(this), TQT_SLOT(zoomMinus()), TQT_TQOBJECT(this), "zoomOut" ); + + l->addWidget(m_page); + + connect(m_page->zoom, TQT_SIGNAL(valueChanged(int)), TQT_SLOT(zoomValueChanged(int))); + connect(m_page->bn100, TQT_SIGNAL(clicked()), TQT_SLOT(zoom100())); + connect(m_page->slZoom, TQT_SIGNAL(valueChanged(int)), TQT_SLOT(sliderChanged( int ))); +} + +KoBirdEyePanel::~KoBirdEyePanel() +{ + delete m_canvas; + delete m_thumbnailProvider; + delete m_zoomListener; +} + +void KoBirdEyePanel::setZoom(int zoom) +{ + m_page->zoom->blockSignals(true); + m_page->slZoom->blockSignals(true); + + m_page->zoom->setValue(zoom); + + if (zoom < 10) { + m_page->slZoom->setValue(0); + } + else if (zoom > 10 && zoom < 100) { + m_page->slZoom->setValue(zoom / 10); + } + else if (zoom >= 100 && zoom < 150) { + m_page->slZoom->setValue(10); + } + else if (zoom >= 150 && zoom < 250) { + m_page->slZoom->setValue(11); + } + else if (zoom >= 250 && zoom < 350) { + m_page->slZoom->setValue(12); + } + else if (zoom >= 350 && zoom < 450) { + m_page->slZoom->setValue(13); + } + else if (zoom >= 450 && zoom < 550) { + m_page->slZoom->setValue(14); + } + else if (zoom >= 550 && zoom < 650) { + m_page->slZoom->setValue(15); + } + else if (zoom >= 650 && zoom < 875) { + m_page->slZoom->setValue(16); + } + else if (zoom >= 875 && zoom < 1150) { + m_page->slZoom->setValue(17); + } + else if (zoom >= 1150 && zoom < 1450) { + m_page->slZoom->setValue(18); + } + else if (zoom >= 1450) { + m_page->slZoom->setValue(19); + } + + + m_page->zoom->blockSignals(false); + m_page->slZoom->blockSignals(false); + + +} + +void KoBirdEyePanel::zoomValueChanged(int zoom) +{ + KoPoint center; + center = m_canvas->visibleArea().center(); + m_zoomListener->zoomTo(center.x(), center.y(), zoom / 100.0); + setZoom(zoom); +} + +void KoBirdEyePanel::zoom100() +{ + zoomValueChanged( 100 ); +} + +void KoBirdEyePanel::sliderChanged( int v ) +{ + if (v < 10) { + zoomValueChanged((v + 1) * 10); + } + else { + switch(v) { + case 10: + zoomValueChanged(100); + break; + case 11: + zoomValueChanged(200); + break; + case 12: + zoomValueChanged(300); + case 13: + zoomValueChanged(400); + break; + case 14: + zoomValueChanged(500); + break; + case 15: + zoomValueChanged(600); + break; + case 16: + zoomValueChanged(750); + break; + case 17: + zoomValueChanged(1000); + break; + case 18: + zoomValueChanged(1300); + break; + case 19: + zoomValueChanged(1600); + break; + } + } +} + +void KoBirdEyePanel::cursorPosChanged(TQ_INT32 xpos, TQ_INT32 ypos) +{ + m_page->txtX->setText(TQString("%L1").tqarg(xpos, 5)); + m_page->txtY->setText(TQString("%L1").tqarg(ypos, 5)); +} + +void KoBirdEyePanel::setThumbnailProvider(KoThumbnailAdapter * thumbnailProvider) +{ + delete m_thumbnailProvider; + m_thumbnailProvider = thumbnailProvider; +} + +void KoBirdEyePanel::slotViewTransformationChanged() +{ + updateVisibleArea(); + renderView(); + m_page->view->update(); + setZoom(tqRound(m_canvas->zoomFactor() * 100)); +} + +void KoBirdEyePanel::slotUpdate(const TQRect & r) +{ + TQRect updateRect = r; + + if (m_thumbnailProvider->pixelSize() != m_documentSize) { + m_documentSize = m_thumbnailProvider->pixelSize(); + fitThumbnailToView(); + updateRect = TQRect(0, 0, m_documentSize.width(), m_documentSize.height()); + } + + updateRect &= TQRect(0, 0, m_documentSize.width(), m_documentSize.height()); + + if (!updateRect.isEmpty() && !m_documentSize.isEmpty()) { + + TQRect thumbnailRect = documentToThumbnail(KoRect::fromTQRect(updateRect)); + + if (!thumbnailRect.isEmpty()) { + + TQImage thumbnailImage = m_thumbnailProvider->image(thumbnailRect, m_thumbnail.size()); + + if (!thumbnailImage.isNull()) { + + Q_ASSERT(thumbnailImage.size() == thumbnailRect.size()); + + TQPainter painter(&m_thumbnail); + + painter.fillRect(thumbnailRect, tqcolorGroup().mid()); + painter.drawImage(thumbnailRect.x(), thumbnailRect.y(), thumbnailImage); + } + } + } + + renderView(); + m_page->view->update(); +} + +TQRect KoBirdEyePanel::documentToThumbnail(const KoRect& docRect) +{ + if (docRect.isEmpty() || m_documentSize.isEmpty() || m_thumbnail.isNull()) { + return TQRect(); + } + + TQ_INT32 thumbnailLeft = static_cast<TQ_INT32>((docRect.left() * m_thumbnail.width()) / m_documentSize.width()); + TQ_INT32 thumbnailRight = static_cast<TQ_INT32>(((docRect.right() + 1) * m_thumbnail.width()) / m_documentSize.width()); + TQ_INT32 thumbnailTop = static_cast<TQ_INT32>((docRect.top() * m_thumbnail.height()) / m_documentSize.height()); + TQ_INT32 thumbnailBottom = static_cast<TQ_INT32>(((docRect.bottom() + 1) * m_thumbnail.height()) / m_documentSize.height()); + + TQRect thumbnailRect(thumbnailLeft, thumbnailTop, thumbnailRight - thumbnailLeft + 1, thumbnailBottom - thumbnailTop + 1); + thumbnailRect &= m_thumbnail.rect(); + + return thumbnailRect; +} + +KoRect KoBirdEyePanel::thumbnailToDocument(const TQRect& thumbnailRect) +{ + if (thumbnailRect.isEmpty() || m_documentSize.isEmpty() || m_thumbnail.isNull()) { + return KoRect(); + } + + double docLeft = (static_cast<double>(thumbnailRect.left()) * m_documentSize.width()) / m_thumbnail.width(); + double docRight = (static_cast<double>(thumbnailRect.right() + 1) * m_documentSize.width()) / m_thumbnail.width(); + double docTop = (static_cast<double>(thumbnailRect.top()) * m_documentSize.height()) / m_thumbnail.height(); + double docBottom = (static_cast<double>(thumbnailRect.bottom() + 1) * m_documentSize.height()) / m_thumbnail.height(); + + KoRect docRect(docLeft, docTop, docRight - docLeft + 1, docBottom - docTop + 1); + docRect &= KoRect(0, 0, m_documentSize.width(), m_documentSize.height()); + + return docRect; +} + +TQPoint KoBirdEyePanel::viewToThumbnail(const TQPoint& viewPoint) +{ + int thumbnailX = (m_viewBuffer.width() - m_thumbnail.width()) / 2; + int thumbnailY = (m_viewBuffer.height() - m_thumbnail.height()) / 2; + + return TQPoint(viewPoint.x() - thumbnailX, viewPoint.y() - thumbnailY); +} + + +void KoBirdEyePanel::zoomMinus() +{ +} + +void KoBirdEyePanel::zoomPlus() +{ +} + +void KoBirdEyePanel::updateVisibleArea() +{ + m_visibleAreaInThumbnail = documentToThumbnail(m_canvas->visibleArea()); +} + + +bool KoBirdEyePanel::eventFilter(TQObject* o, TQEvent* ev) +{ + if (TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(m_page->view) && ev->type() == TQEvent::Resize) { + resizeViewEvent(TQT_TQRESIZEEVENT(ev)->size()); + } + + if (TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(m_page->view) && ev->type() == TQEvent::Paint) { + paintViewEvent(TQT_TQPAINTEVENT(ev)); + } + + if (TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(m_page->view) && ev->type() == TQEvent::MouseMove) { + + TQMouseEvent* me = (TQMouseEvent*)ev; + TQPoint thumbnailPos = viewToThumbnail(me->pos()); + + if (m_dragging) { + handleMouseMoveAction(thumbnailPos); + } else { + handleMouseMove(thumbnailPos); + } + + return true; + } + + if (TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(m_page->view) && ev->type() == TQEvent::MouseButtonPress) { + + TQMouseEvent* me = (TQMouseEvent*)ev; + TQPoint thumbnailPos = viewToThumbnail(me->pos()); + + if (me->button() == Qt::LeftButton) { + handleMousePress(thumbnailPos); + } + + return true; + } + + if (TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(m_page->view) && ev->type() == TQEvent::MouseButtonRelease) { + + TQMouseEvent* me = (TQMouseEvent*)ev; + + if (me->button() == Qt::LeftButton) { + m_dragging = false; + } + + return true; + } + + return m_page->eventFilter(o, ev); +} + +KoBirdEyePanel::enumDragHandle KoBirdEyePanel::dragHandleAt(TQPoint p) +{ + TQRect left = TQRect(m_visibleAreaInThumbnail.left()-1, m_visibleAreaInThumbnail.top()-1, 3, m_visibleAreaInThumbnail.height()+2); + TQRect right = TQRect(m_visibleAreaInThumbnail.right()-1, m_visibleAreaInThumbnail.top()-1, 3, m_visibleAreaInThumbnail.height()+2); + TQRect top = TQRect(m_visibleAreaInThumbnail.left()-1, m_visibleAreaInThumbnail.top()-1, m_visibleAreaInThumbnail.width()+2, 3); + TQRect bottom = TQRect(m_visibleAreaInThumbnail.left()-1, m_visibleAreaInThumbnail.bottom()-1, m_visibleAreaInThumbnail.width()+2, 3); + + if (left.tqcontains(p)) { + return DragHandleLeft; + } + + if (right.tqcontains(p)) { + return DragHandleRight; + } + + if (top.tqcontains(p)) { + return DragHandleTop; + } + + if (bottom.tqcontains(p)) { + return DragHandleBottom; + } + + if (m_visibleAreaInThumbnail.tqcontains(p)) { + return DragHandleCentre; + } + + return DragHandleNone; +} + +void KoBirdEyePanel::handleMouseMove(TQPoint p) +{ + TQCursor cursor; + + switch (dragHandleAt(p)) { + case DragHandleLeft: + case DragHandleRight: + cursor = TQt::sizeHorCursor; + break; + case DragHandleTop: + case DragHandleBottom: + cursor = TQt::sizeVerCursor; + break; + case DragHandleCentre: + cursor = TQt::sizeAllCursor; + break; + default: + case DragHandleNone: + if (TQT_TQRECT_OBJECT(m_thumbnail.rect()).tqcontains(p)) { + cursor = TQt::PointingHandCursor; + } else { + cursor = TQt::arrowCursor; + } + break; + } + + m_page->view->setCursor(cursor); +} + +void KoBirdEyePanel::handleMouseMoveAction(TQPoint p) +{ + if (m_dragging) { + + TQ_INT32 dx = p.x() - m_lastDragPos.x(); + TQ_INT32 dy = p.y() - m_lastDragPos.y(); + + m_lastDragPos = p; + + TQRect thumbnailRect = m_visibleAreaInThumbnail; + + switch (m_dragHandle) { + case DragHandleLeft: { + thumbnailRect.setLeft(thumbnailRect.left()+dx); + break; + } + case DragHandleRight: { + thumbnailRect.setRight(thumbnailRect.right()+dx); + break; + } + case DragHandleTop: { + thumbnailRect.setTop(thumbnailRect.top()+dy); + break; + } + case DragHandleBottom: { + thumbnailRect.setBottom(thumbnailRect.bottom()+dy); + break; + } + case DragHandleCentre: { + thumbnailRect.moveBy(dx, dy); + break; + } + default: + case DragHandleNone: + break; + } + + makeThumbnailRectVisible(thumbnailRect); + } +} + +void KoBirdEyePanel::handleMousePress(TQPoint p) +{ + if (!m_dragging) { + + enumDragHandle dragHandle = dragHandleAt(p); + + if (dragHandle == DragHandleNone) { + if (TQT_TQRECT_OBJECT(m_thumbnail.rect()).tqcontains(p)) { + + // Snap visible area centre to p and begin a centre drag. + + TQRect thumbnailRect = m_visibleAreaInThumbnail; + thumbnailRect.moveCenter(p); + makeThumbnailRectVisible(thumbnailRect); + + m_dragHandle = DragHandleCentre; + m_page->view->setCursor(TQt::sizeAllCursor); + m_dragging = true; + } + } else { + m_dragHandle = dragHandle; + m_dragging = true; + } + m_lastDragPos = p; + } +} + +void KoBirdEyePanel::makeThumbnailRectVisible(const TQRect& r) +{ + if (r.isEmpty()) { + return; + } + + TQRect thumbnailRect = r; + + if (thumbnailRect.left() < m_thumbnail.rect().left()) { + thumbnailRect.moveLeft(m_thumbnail.rect().left()); + } + if (thumbnailRect.right() > m_thumbnail.rect().right()) { + thumbnailRect.moveRight(m_thumbnail.rect().right()); + } + if (thumbnailRect.top() < m_thumbnail.rect().top()) { + thumbnailRect.moveTop(m_thumbnail.rect().top()); + } + if (thumbnailRect.bottom() > m_thumbnail.rect().bottom()) { + thumbnailRect.moveBottom(m_thumbnail.rect().bottom()); + } + + if (thumbnailRect.width() > m_thumbnail.rect().width()) { + thumbnailRect.setLeft(m_thumbnail.rect().left()); + thumbnailRect.setRight(m_thumbnail.rect().right()); + } + if (thumbnailRect.height() > m_thumbnail.rect().height()) { + thumbnailRect.setTop(m_thumbnail.rect().top()); + thumbnailRect.setBottom(m_thumbnail.rect().bottom()); + } + + double zoomFactor = m_canvas->zoomFactor(); + + if (thumbnailRect.size() == m_visibleAreaInThumbnail.size()) { + // No change to zoom + } else if (thumbnailRect.width() != m_visibleAreaInThumbnail.width()) { + + Q_ASSERT(thumbnailRect.height() == m_visibleAreaInThumbnail.height()); + + zoomFactor *= static_cast<double>(m_visibleAreaInThumbnail.width()) / thumbnailRect.width(); + } else { + + Q_ASSERT(thumbnailRect.width() == m_visibleAreaInThumbnail.width()); + + zoomFactor *= static_cast<double>(m_visibleAreaInThumbnail.height()) / thumbnailRect.height(); + } + + if (zoomFactor < m_zoomListener->getMinZoom()) { + zoomFactor = m_zoomListener->getMinZoom(); + } else if (zoomFactor > m_zoomListener->getMaxZoom()) { + zoomFactor = m_zoomListener->getMaxZoom(); + } + + KoRect docRect = thumbnailToDocument(thumbnailRect); + m_zoomListener->zoomTo(docRect.center().x(), docRect.center().y(), zoomFactor); +} + +void KoBirdEyePanel::resizeViewEvent(TQSize size) +{ + m_viewBuffer.resize(size); + fitThumbnailToView(); + slotUpdate(TQRect(0, 0, m_documentSize.width(), m_documentSize.height())); +} + +void KoBirdEyePanel::fitThumbnailToView() +{ + TQRect docRect = TQRect(0, 0, m_thumbnailProvider->pixelSize().width(), m_thumbnailProvider->pixelSize().height()); + TQ_INT32 thumbnailWidth; + TQ_INT32 thumbnailHeight; + + if (docRect.isEmpty()) { + thumbnailWidth = 0; + thumbnailHeight = 0; + } else { + const int thumbnailBorderPixels = 4; + + double xScale = double(m_page->view->contentsRect().width() - thumbnailBorderPixels) / docRect.width(); + double yScale = double(m_page->view->contentsRect().height() - thumbnailBorderPixels) / docRect.height(); + + if (xScale < yScale) { + thumbnailWidth = m_page->view->contentsRect().width() - thumbnailBorderPixels; + thumbnailHeight = TQ_INT32(ceil(docRect.height() * xScale)); + } else { + thumbnailWidth = TQ_INT32(ceil(docRect.width() * yScale)); + thumbnailHeight = m_page->view->contentsRect().height() - thumbnailBorderPixels; + } + } + + m_thumbnail.resize(thumbnailWidth, thumbnailHeight); + updateVisibleArea(); +} + +void KoBirdEyePanel::renderView() +{ + Q_ASSERT(!m_viewBuffer.isNull()); + + if (!m_viewBuffer.isNull()) { + + updateVisibleArea(); + + TQPainter painter(&m_viewBuffer); + + painter.fillRect(0, 0, m_viewBuffer.width(), m_viewBuffer.height(), tqcolorGroup().mid()); + + if (!m_thumbnail.isNull()) { + + int thumbnailX = (m_viewBuffer.width() - m_thumbnail.width()) / 2; + int thumbnailY = (m_viewBuffer.height() - m_thumbnail.height()) / 2; + + painter.drawPixmap(thumbnailX, thumbnailY, m_thumbnail); + + painter.setPen(TQt::red); + painter.drawRect(thumbnailX + m_visibleAreaInThumbnail.x() - 1, + thumbnailY + m_visibleAreaInThumbnail.y() - 1, + m_visibleAreaInThumbnail.width() + 2, + m_visibleAreaInThumbnail.height() + 2); + painter.setPen(TQt::red.light()); + painter.drawRect(thumbnailX + m_visibleAreaInThumbnail.x() - 2, + thumbnailY + m_visibleAreaInThumbnail.y() - 2, + m_visibleAreaInThumbnail.width() + 4, + m_visibleAreaInThumbnail.height() + 4); + } + } +} + +void KoBirdEyePanel::paintViewEvent(TQPaintEvent *e) +{ + Q_ASSERT(!m_viewBuffer.isNull()); + + if (!m_viewBuffer.isNull()) { + bitBlt(m_page->view, e->rect().x(), e->rect().y(), &m_viewBuffer, + e->rect().x(), e->rect().y(), e->rect().width(), e->rect().height()); + } +} + +#include "kobirdeyepanel.moc" diff --git a/chalk/ui/kobirdeyepanel.h b/chalk/ui/kobirdeyepanel.h new file mode 100644 index 00000000..24770b18 --- /dev/null +++ b/chalk/ui/kobirdeyepanel.h @@ -0,0 +1,263 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org> + * + * 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 2 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KO_BIRD_EYE_PANEL +#define KO_BIRD_EYE_PANEL + +#include <tqrect.h> +#include <tqwidget.h> + +#include <KoPoint.h> +#include <KoRect.h> + +class TQPixmap; +class KAction; +class KoDocument; +class WdgBirdEye; + + +class KoCanvasAdapter { + +public: + + KoCanvasAdapter(); + virtual ~KoCanvasAdapter(); + + /** + * Returns the area of the document that is visible, in pixels + */ + virtual KoRect visibleArea() = 0; + + /** + * Returns the total area of the document in pixels. Use KoPageLayout and KoZoomhandler + * to take care of zoom, points and whatnot when computing this. + */ + virtual TQRect size() = 0; + + /** + * Return the current canvas zoom factor. + */ + virtual double zoomFactor() = 0; + + /** + * Show pt in the center of the view + */ + virtual void setViewCenterPoint(double x, double y) = 0; +}; + +/** + * The zoom listener interface defines methods that the bird eye + * panel will call whenever the zoomlevel is changed through one + * of the panel actions. + */ +class KoZoomAdapter { + +public: + + KoZoomAdapter(); + virtual ~KoZoomAdapter(); + + /** + * Zoom to the specified factor around the point x and y + */ + virtual void zoomTo(double x, double y, double factor ) = 0; + + /** + * Zoom one step in. + */ + virtual void zoomIn() = 0; + + /** + * Zoom one step out. + */ + virtual void zoomOut() = 0; + + /** + * Get the minimum zoom factor that this listener supports. + */ + virtual double getMinZoom() = 0; + + /** + * Get the maximum zoom factor that this listener supports. + */ + virtual double getMaxZoom() = 0; + +}; + + +class KoThumbnailAdapter +{ + public: + + KoThumbnailAdapter(); + ~KoThumbnailAdapter(); + + /** + * Returns the size of the document in pixels. + * If the document is a KoDocument that uses a KoPageLayout, the same + * formula as in the generatePreview() method should be used to go from points + * to pixels. + * + * @returns the size in pixels. + */ + virtual TQSize pixelSize() = 0; + + /** + * Returns the specified rectangle of the thumbnail as a TQImage. thumbnailSize + * gives the dimensions of the whole document thumbnail, and r specifies a rectangle + * within that. + * + * @param r the rectangle in the thumbnail to be rendered + * @param thumbnailSize the size in pixels of the full thumbnail + */ + virtual TQImage image(TQRect r, TQSize thumbnailSize) = 0; +}; + +/** + * A complex widget that provides an overview of a document + * with a red panning rectangle to and a zoom slider and a toolbar + * with a couple of useful functions. + */ +class KoBirdEyePanel : public TQWidget { + + Q_OBJECT + TQ_OBJECT + +public: + + /** + * Create a new bird eye panel. + * + * @param zoomListener the object that listens to the zoom instructions we give + * @param thumbnailProvider the class that creates the small image at the right + * zoomlevel + * @param canvas the place the document is painted. + * @param tqparent the tqparent widget + * @param name the TQObject name of this bird eye widget + * @param f the widget flags (@see TQWidget) + */ + KoBirdEyePanel( KoZoomAdapter * zoomListener, + KoThumbnailAdapter * thumbnailProvider, + KoCanvasAdapter * canvas, + TQWidget * tqparent, + const char * name = 0, + WFlags f = 0 ); + + virtual ~KoBirdEyePanel(); + + bool eventFilter(TQObject*, TQEvent*); + +public slots: + + void setZoomListener( KoZoomAdapter * zoomListener) { m_zoomListener = zoomListener; } + + /** + * Set a new thumbnail provider. This will first delete the existing provider. + **/ + void setThumbnailProvider( KoThumbnailAdapter * thumbnailProvider ); + + /** + * Connect to this slot to inform the bird's eye view of changes in + * the view transformation, i.e. zoom level or scroll changes. + */ + void slotViewTransformationChanged(); + + void cursorPosChanged(TQ_INT32 xpos, TQ_INT32 ypos); + + void zoomMinus(); + void zoomPlus(); + + /** + * Connect to this slot if a (rectangular) area of your document is changed. + * + * @param r The rect that has been changed: this is unzoomed. + */ + void slotUpdate(const TQRect & r); + +protected slots: + + void updateVisibleArea(); + void zoomValueChanged(int zoom); + void zoom100(); + void sliderChanged(int); + +protected: + void setZoom(int zoom); + + void handleMouseMove(TQPoint); + void handleMouseMoveAction(TQPoint); + void handleMousePress(TQPoint); + void fitThumbnailToView(); + void renderView(); + void resizeViewEvent(TQSize size); + void paintViewEvent(TQPaintEvent *e); + void makeThumbnailRectVisible(const TQRect& r); + + enum enumDragHandle { + DragHandleNone, + DragHandleLeft, + DragHandleCentre, + DragHandleRight, + DragHandleTop, + DragHandleBottom + }; + + /* + * Returns the drag handle type at point p in thumbnail coordinates. + */ + enumDragHandle dragHandleAt(TQPoint p); + + /** + * Returns the rectangle in the thumbnail covered by the given document rectangle. + */ + TQRect documentToThumbnail(const KoRect& docRect); + + /** + * Returns the rectangle in the document covered by the given thumbnail rectangle. + */ + KoRect thumbnailToDocument(const TQRect& thumbnailRect); + + /** + * Converts a point in the view to a point in the thumbnail. + */ + TQPoint viewToThumbnail(const TQPoint& viewPoint); + +private: + + WdgBirdEye * m_page; + + KoZoomAdapter * m_zoomListener; + KoThumbnailAdapter * m_thumbnailProvider; + KoCanvasAdapter * m_canvas; + + KAction* m_zoomIn; + KAction* m_zoomOut; + TQPixmap m_viewBuffer; + TQPixmap m_thumbnail; + + TQSize m_documentSize; + TQRect m_visibleAreaInThumbnail; + bool m_dragging; + enumDragHandle m_dragHandle; + TQPoint m_lastDragPos; + +}; + +#endif diff --git a/chalk/ui/layerlist.cpp b/chalk/ui/layerlist.cpp new file mode 100644 index 00000000..976ec84d --- /dev/null +++ b/chalk/ui/layerlist.cpp @@ -0,0 +1,1325 @@ +/* + Copyright (c) 2005 Gábor Lehel <illissius@gmail.com> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + + +#include "layerlist.h" + +#include <tqtooltip.h> +#include <tqbitmap.h> +#include <tqcursor.h> +#include <tqimage.h> +#include <tqheader.h> +#include <tqpainter.h> +#include <tqpixmap.h> +#include <tqsimplerichtext.h> +#include <tqtimer.h> + +#include <kapplication.h> +#include <kdebug.h> +#include <kglobal.h> +#include <kglobalsettings.h> +#include <kiconloader.h> +#include <klineedit.h> +#include <klocale.h> +#include <kpopupmenu.h> +#include <kstringhandler.h> + +class LayerItemIterator: public TQListViewItemIterator +{ +public: + LayerItemIterator( LayerList *list ): TQListViewItemIterator( list ) { } + LayerItemIterator( LayerList *list, IteratorFlag flags ): TQListViewItemIterator( list, flags ) { } + LayerItemIterator( LayerItem *item ): TQListViewItemIterator( item ) { } + LayerItemIterator( LayerItem *item, IteratorFlag flags ): TQListViewItemIterator( item, flags ) { } + LayerItem *operator*() { return static_cast<LayerItem*>( TQListViewItemIterator::operator*() ); } +}; + +struct LayerProperty +{ + TQString name; + TQString displayName; + TQPixmap enabledIcon; + TQPixmap disabledIcon; + bool defaultValue; + bool validForFolders; + + LayerProperty(): defaultValue( false ), validForFolders( true ) { } + LayerProperty( const TQString &pname, const TQString &pdisplayName, const TQPixmap &enabled, const TQPixmap &disabled, + bool pdefaultValue, bool pvalidForFolders ) + : name( pname ), + displayName( pdisplayName ), + enabledIcon( enabled ), + disabledIcon( disabled ), + defaultValue( pdefaultValue ), + validForFolders( pvalidForFolders ) + { } +}; + +class LayerToolTip; +class LayerList::Private +{ +public: + LayerItem *activeLayer; + bool foldersCanBeActive; + bool previewsShown; + int itemHeight; + TQValueList<LayerProperty> properties; + KPopupMenu contextMenu; + LayerToolTip *tooltip; + + Private( TQWidget *tqparent, LayerList *list ); + ~Private(); +}; + +class LayerItem::Private +{ +public: + bool isFolder; + int id; + TQValueList<bool> properties; + TQImage *previewImage; + bool previewChanged; + TQPixmap scaledPreview; + TQSize previewSize; + TQPoint previewOffset; + + Private( int pid ): isFolder( false ), id( pid ), previewImage( 0 ), previewChanged( false ) + { } +}; + +static const int MAX_SIZE = 256; +class LayerToolTip: public TQToolTip, public TQFrame +{ + LayerList *m_list; + LayerItem *m_item; + TQPoint m_pos; + TQTimer m_timer; + TQImage m_img; + +public: + LayerToolTip( TQWidget *tqparent, LayerList *list ) + : TQToolTip( tqparent ), + TQFrame( 0, 0, WStyle_Customize | WStyle_NoBorder | WStyle_Tool | WStyle_StaysOnTop | WX11BypassWM | WNoAutoErase ), + m_list( list ) + { + TQFrame::setPalette( TQToolTip::palette() ); + connect( &m_timer, TQT_SIGNAL( timeout() ), m_list, TQT_SLOT( hideTip() ) ); + tqApp->installEventFilter( this ); + } + + virtual void maybeTip( const TQPoint &pos ) + { + m_pos = pos; + LayerItem *prev = m_item; + m_item = static_cast<LayerItem*>(m_list->itemAt( m_pos )); + if( TQToolTip::tqparentWidget() && m_list->showToolTips() && m_item ) + { + if( m_item != prev ) + hideTip(); + showTip(); + } + else + hideTip(); + } + + void showTip() + { + m_img = m_item->tooltipPreview(); + m_timer.start( 15000, true ); + if( !isVisible() || tqsizeHint() != size() ) + { + resize( tqsizeHint() ); + position(); + } + if( !isVisible() ) + show(); + else + update(); + } + + void hideTip() + { + if( !isVisible() ) + return; + TQFrame::hide(); + TQToolTip::hide(); + m_timer.stop(); + m_img.reset(); + m_list->triggerUpdate(); + } + + virtual void drawContents( TQPainter *painter ) + { + TQPixmap buf( width(), height() ); + TQPainter p( &buf ); + buf.fill( tqcolorGroup().background() ); + p.setPen( tqcolorGroup().foreground() ); + p.drawRect( buf.rect() ); + + TQSimpleRichText text( m_item->tooltip(), TQToolTip::font() ); + text.setWidth( TQCOORD_MAX ); + + p.translate( 5, 5 ); + if( !m_img.isNull() ) + { + if( m_img.width() > MAX_SIZE || m_img.height() > MAX_SIZE ) + m_img = m_img.scale( MAX_SIZE, MAX_SIZE, TQ_ScaleMin ); + int y = 0; + if( m_img.height() < text.height() ) + y = text.height()/2 - m_img.height()/2; + p.drawImage( 0, y, m_img ); + p.drawRect( -1, y-1, m_img.width()+2, m_img.height()+2 ); + p.translate( m_img.width() + 10, 0 ); + } + + text.draw( &p, 0, 0, rect(), tqcolorGroup() ); + + painter->drawPixmap( 0, 0, buf ); + } + + virtual TQSize tqsizeHint() const + { + if( !m_item ) + return TQSize( 0, 0 ); + + TQSimpleRichText text( m_item->tooltip(), TQToolTip::font() ); + text.setWidth( TQCOORD_MAX ); + + int width = text.widthUsed(); + if( !m_img.isNull() ) + width += kMin( m_img.width(), MAX_SIZE ) + 10; + width += 10; + + int height = text.height(); + if( !m_img.isNull() && kMin( m_img.height(), MAX_SIZE ) > height ) + height = kMin( m_img.height(), MAX_SIZE ); + height += 10; + + return TQSize( width, height ); + } + + void position() + { + const TQRect drect = TQApplication::desktop()->availableGeometry( TQToolTip::tqparentWidget() ); + const TQSize size = tqsizeHint(); + const int width = size.width(), height = size.height(); + const TQRect tmp = m_item->rect(); + const TQRect irect( m_list->viewport()->mapToGlobal( m_list->contentsToViewport(tmp.topLeft()) ), tmp.size() ); + + int y; + if( irect.bottom() + height < drect.bottom() ) + y = irect.bottom(); + else + y = kMax( drect.top(), irect.top() - height ); + + int x = kMax( drect.x(), TQToolTip::tqparentWidget()->mapToGlobal( m_pos ).x() - width/2 ); + if( x + width > drect.right() ) + x = drect.right() - width; + + move( x, y ); + } + + virtual bool eventFilter( TQObject *, TQEvent *e ) + { + if( isVisible() ) + switch ( e->type() ) + { + case TQEvent::KeyPress: + case TQEvent::KeyRelease: + case TQEvent::MouseButtonPress: + case TQEvent::MouseButtonRelease: + //case TQEvent::MouseMove: + case TQEvent::FocusIn: + case TQEvent::FocusOut: + case TQEvent::Wheel: + case TQEvent::Leave: + hideTip(); + default: break; + } + + return false; + } +}; + +LayerList::Private::Private( TQWidget *tqparent, LayerList *list ) + : activeLayer( 0 ), foldersCanBeActive( false ), previewsShown( false ), itemHeight( 32 ), + tooltip( new LayerToolTip( tqparent, list ) ) { } + +LayerList::Private::~Private() +{ + delete tooltip; + tooltip = 0; +} + +static int getID() +{ + static int id = -2; + return id--; +} + +static TQSize iconSize() { return TQIconSet::iconSize( TQIconSet::Small ); } + + +/////////////// +// LayerList // +/////////////// + +LayerList::LayerList( TQWidget *tqparent, const char *name ) + : super( tqparent, name ), d( new Private( viewport(), this ) ) +{ + setSelectionMode( TQListView::Extended ); + setRootIsDecorated( true ); + setSorting( -1 ); + setSortColumn( -1 ); + setAllColumnsShowFocus( true ); + setFullWidth( true ); + setItemsRenameable( false ); + setDropHighlighter( true ); + setDefaultRenameAction( TQListView::Accept ); + setDragEnabled( true ); + setAcceptDrops( true ); + setItemsMovable( true ); + addColumn( TQString() ); + header()->hide(); + + TQToolTip::add(this, i18n("Right-click to create folders. Click on the layername to change the layer's name. Click and drag to move layers.")); + + setNumRows( 2 ); + + connect( this, TQT_SIGNAL( itemRenamed( TQListViewItem*, const TQString&, int ) ), + TQT_SLOT( slotItemRenamed( TQListViewItem*, const TQString&, int ) ) ); + connect( this, TQT_SIGNAL( moved( TQPtrList<TQListViewItem>&, TQPtrList<TQListViewItem>&, TQPtrList<TQListViewItem>& ) ), + TQT_SLOT( slotItemMoved( TQPtrList<TQListViewItem>&, TQPtrList<TQListViewItem>&, TQPtrList<TQListViewItem>& ) ) ); + connect( this, TQT_SIGNAL( onItem( TQListViewItem* ) ), TQT_SLOT( hideTip() ) ); + connect( this, TQT_SIGNAL( onViewport() ), TQT_SLOT( hideTip() ) ); +} + +LayerList::~LayerList() +{ + delete d; +} + +void LayerList::addProperty( const TQString &name, const TQString &displayName, const TQIconSet &icon, + bool defaultValue, bool validForFolders ) +{ + addProperty( name, displayName, icon.pixmap( TQIconSet::Small, TQIconSet::Normal ), icon.pixmap( TQIconSet::Small, TQIconSet::Disabled ), defaultValue, validForFolders ); +} + +void LayerList::addProperty( const TQString &name, const TQString &displayName, TQPixmap enabled, TQPixmap disabled, + bool defaultValue, bool validForFolders ) +{ + d->properties.append( LayerProperty( name, displayName, enabled, disabled, defaultValue, validForFolders ) ); + + for( LayerItemIterator it( this ); *it; ++it ) + (*it)->d->properties.append( defaultValue ); + + //we do this only afterwards in case someone wants to access the other items in a connected slot... + for( LayerItemIterator it( this ); *it; ++it ) + if( validForFolders || !(*it)->isFolder() ) + { + emit propertyChanged( *it, name, defaultValue ); + emit propertyChanged( (*it)->id(), name, defaultValue ); + } + + triggerUpdate(); +} + +LayerItem *LayerList::layer( int id ) const +{ + if( !firstChild() || id == -1 ) + return 0; + + for( LayerItemIterator it( firstChild() ); *it; ++it ) + if( (*it)->id() == id ) + return (*it); + + return 0; +} + +LayerItem *LayerList::folder( int id ) const +{ + if( !firstChild() || id == -1 ) + return 0; + + for( LayerItemIterator it( firstChild() ); *it; ++it ) + if( (*it)->id() == id && (*it)->isFolder() ) + return (*it); + + return 0; +} + +LayerItem *LayerList::activeLayer() const +{ + return d->activeLayer; +} + +int LayerList::activeLayerID() const +{ + if( activeLayer() ) + return activeLayer()->id(); + return -1; +} + +TQValueList<LayerItem*> LayerList::selectedLayers() const +{ + if( !firstChild() ) + return TQValueList<LayerItem*>(); + + TQValueList<LayerItem*> layers; + for( LayerItemIterator it( firstChild() ); *it; ++it ) + if( (*it)->isSelected() ) + layers.append( *it ); + + return layers; +} + +TQValueList<int> LayerList::selectedLayerIDs() const +{ + const TQValueList<LayerItem*> layers = selectedLayers(); + TQValueList<int> ids; + for( int i = 0, n = layers.count(); i < n; ++i ) + ids.append( layers[i]->id() ); + + return ids; +} + +bool LayerList::foldersCanBeActive() const +{ + return d->foldersCanBeActive; +} + +bool LayerList::previewsShown() const +{ + return d->previewsShown; +} + +int LayerList::itemHeight() const +{ + return d->itemHeight; +} + +int LayerList::numRows() const +{ + if( itemHeight() < kMax( fontMetrics().height(), iconSize().height() ) ) + return 0; + + return ( itemHeight() - fontMetrics().height() ) / iconSize().height() + 1; +} + +void LayerList::makeFolder( int id ) +{ + LayerItem* const l = layer( id ); + if( l ) + l->makeFolder(); +} + +bool LayerList::isFolder( int id ) const +{ + LayerItem* const l = layer( id ); + if( !l ) + return false; + + return l->isFolder(); +} + +TQString LayerList::displayName( int id ) const +{ + LayerItem* const l = layer( id ); + if( !l ) + return TQString(); //should be more severe... + + return l->displayName(); +} + +bool LayerList::property( int id, const TQString &name ) const +{ + LayerItem* const l = layer( id ); + if( !l ) + return false; //should be more severe... + + return l->property( name ); +} + +KPopupMenu *LayerList::contextMenu() const +{ + return &( d->contextMenu ); +} + +void LayerList::setFoldersCanBeActive( bool can ) //SLOT +{ + d->foldersCanBeActive = can; + if( !can && activeLayer() && activeLayer()->isFolder() ) + { + d->activeLayer = 0; + emit activated( static_cast<LayerItem*>( 0 ) ); + emit activated( -1 ); + } +} + +void LayerList::setPreviewsShown( bool show ) //SLOT +{ + d->previewsShown = show; + triggerUpdate(); +} + +void LayerList::setItemHeight( int height ) //SLOT +{ + d->itemHeight = height; + for( LayerItemIterator it( this ); *it; ++it ) + (*it)->setup(); + triggerUpdate(); +} + +void LayerList::setNumRows( int rows ) +{ + if( rows < 1 ) + return; + + if( rows == 1 ) + setItemHeight( kMax( fontMetrics().height(), iconSize().height() ) ); + else + setItemHeight( fontMetrics().height() + ( rows - 1 ) * iconSize().height() ); +} + +void LayerList::setActiveLayer( LayerItem *layer ) //SLOT +{ + if( !foldersCanBeActive() && layer && layer->isFolder() ) + return; + + ensureItemVisible( layer ); + + if( d->activeLayer == layer ) + return; + + d->activeLayer = layer; + + if( currentItem() != layer ) + setCurrentItem( layer ); + else + { + int n = 0; + for( LayerItemIterator it( this, LayerItemIterator::Selected ); n < 2 && (*it); ++it ) { n++; } + if( n == 1 ) + (*LayerItemIterator( this, LayerItemIterator::Selected ))->setSelected( false ); + if( layer ) + layer->setSelected( true ); + } + + emit activated( layer ); + if( layer ) + emit activated( layer->id() ); + else + emit activated( -1 ); +} + +void LayerList::setActiveLayer( int id ) //SLOT +{ + setActiveLayer( layer( id ) ); +} + +void LayerList::setLayerDisplayName( LayerItem *layer, const TQString &displayName ) +{ + if( !layer ) + return; + + layer->setDisplayName( displayName ); +} + +void LayerList::setLayerDisplayName( int id, const TQString &displayName ) +{ + setLayerDisplayName( layer( id ), displayName ); +} + +void LayerList::setLayerProperty( LayerItem *layer, const TQString &name, bool on ) //SLOT +{ + if( !layer ) + return; + + layer->setProperty( name, on ); +} + +void LayerList::setLayerProperty( int id, const TQString &name, bool on ) //SLOT +{ + setLayerProperty( layer( id ), name, on ); +} + +void LayerList::toggleLayerProperty( LayerItem *layer, const TQString &name ) //SLOT +{ + if( !layer ) + return; + + layer->toggleProperty( name ); +} + +void LayerList::toggleLayerProperty( int id, const TQString &name ) //SLOT +{ + toggleLayerProperty( layer( id ), name ); +} + +void LayerList::setLayerPreviewImage( LayerItem *layer, TQImage *image ) +{ + if( !layer ) + return; + + layer->setPreviewImage( image ); +} + +void LayerList::setLayerPreviewImage( int id, TQImage *image ) +{ + setLayerPreviewImage( layer( id ), image ); +} + +void LayerList::layerPreviewChanged( LayerItem *layer ) +{ + if( !layer ) + return; + + layer->previewChanged(); +} + +void LayerList::layerPreviewChanged( int id ) +{ + layerPreviewChanged( layer( id ) ); +} + +LayerItem *LayerList::addLayer( const TQString &displayName, LayerItem *after, int id ) //SLOT +{ + return new LayerItem( displayName, this, after, id ); +} + +LayerItem *LayerList::addLayer( const TQString &displayName, int afterID, int id ) //SLOT +{ + return new LayerItem( displayName, this, layer( afterID ), id ); +} + +//SLOT +LayerItem *LayerList::addLayerToParent( const TQString &displayName, LayerItem *tqparent, LayerItem *after, int id ) +{ + if( tqparent && tqparent->isFolder() ) + return tqparent->addLayer( displayName, after, id ); + else + return 0; +} + +LayerItem *LayerList::addLayerToParent( const TQString &displayName, int tqparentID, int afterID, int id ) //SLOT +{ + return addLayerToParent( displayName, folder( tqparentID ), layer( afterID ), id ); +} + +void LayerList::moveLayer( LayerItem *layer, LayerItem *tqparent, LayerItem *after ) //SLOT +{ + if( !layer ) + return; + + if( tqparent && !tqparent->isFolder() ) + tqparent = 0; + + if( layer->tqparent() == tqparent && layer->prevSibling() == after ) + return; + + TQListViewItem *current = currentItem(); + + moveItem( layer, tqparent, after ); + + emit layerMoved( layer, tqparent, after ); + emit layerMoved( layer->id(), tqparent ? tqparent->id() : -1, after ? after->id() : -1 ); + + setCurrentItem( current ); //HACK, sometimes TQt changes this under us +} + +void LayerList::moveLayer( int id, int tqparentID, int afterID ) //SLOT +{ + moveLayer( layer( id ), folder( tqparentID ), layer( afterID ) ); +} + +void LayerList::removeLayer( LayerItem *layer ) //SLOT +{ + delete layer; +} + +void LayerList::removeLayer( int id ) //SLOT +{ + delete layer( id ); +} + +void LayerList::contentsMousePressEvent( TQMouseEvent *e ) +{ + LayerItem *item = static_cast<LayerItem*>( itemAt( contentsToViewport( e->pos() ) ) ); + + if( item ) + { + TQMouseEvent m( TQEvent::MouseButtonPress, item->mapFromListView( e->pos() ), e->button(), e->state() ); + if( !item->mousePressEvent( &m ) ) + super::contentsMousePressEvent( e ); + } + else + { + super::contentsMousePressEvent( e ); + if( e->button() == Qt::RightButton ) + showContextMenu(); + } +} + +void LayerList::contentsMouseDoubleClickEvent( TQMouseEvent *e ) +{ + super::contentsMouseDoubleClickEvent( e ); + if( LayerItem *layer = static_cast<LayerItem*>( itemAt( contentsToViewport( e->pos() ) ) ) ) + { + if( !layer->iconsRect().tqcontains( layer->mapFromListView( e->pos() ) ) ) + { + emit requestLayerProperties( layer ); + emit requestLayerProperties( layer->id() ); + } + } + else + { + emit requestNewLayer( static_cast<LayerItem*>( 0 ), static_cast<LayerItem*>( 0 ) ); + emit requestNewLayer( -1, -1 ); + } +} + +void LayerList::findDrop( const TQPoint &pos, TQListViewItem *&tqparent, TQListViewItem *&after ) +{ + LayerItem *item = static_cast<LayerItem*>( itemAt( contentsToViewport( pos ) ) ); + if( item && item->isFolder() ) + { + tqparent = item; + after = 0; + } + else + super::findDrop( pos, tqparent, after ); +} + +void LayerList::showContextMenu() +{ + LayerItem *layer = static_cast<LayerItem*>( itemAt( viewport()->mapFromGlobal( TQCursor::pos() ) ) ); + if( layer ) + setCurrentItem( layer ); + d->contextMenu.clear(); + constructMenu( layer ); + menuActivated( d->contextMenu.exec( TQCursor::pos() ), layer ); +} + +void LayerList::hideTip() +{ + d->tooltip->hideTip(); +} + +void LayerList::maybeTip() +{ + d->tooltip->maybeTip( d->tooltip->TQToolTip::tqparentWidget()->mapFromGlobal( TQCursor::pos() ) ); +} + +void LayerList::constructMenu( LayerItem *layer ) +{ + if( layer ) + { + for( int i = 0, n = d->properties.count(); i < n; ++i ) + if( !layer->isFolder() || d->properties[i].validForFolders ) + d->contextMenu.insertItem( layer->d->properties[i] ? d->properties[i].enabledIcon : d->properties[i].disabledIcon, d->properties[i].displayName, MenuItems::COUNT + i ); + d->contextMenu.insertItem( SmallIconSet( "info" ), i18n( "&Properties" ), MenuItems::LayerProperties ); + d->contextMenu.insertSeparator(); + d->contextMenu.insertItem( SmallIconSet( "editdelete" ), + selectedLayers().count() > 1 ? i18n( "Remove Layers" ) + : layer->isFolder() ? i18n( "&Remove Folder" ) + : i18n( "&Remove Layer" ), MenuItems::RemoveLayer ); + } + d->contextMenu.insertItem( SmallIconSet( "filenew" ), i18n( "&New Layer" ), MenuItems::NewLayer ); + d->contextMenu.insertItem( SmallIconSet( "folder" ), i18n( "New &Folder" ), MenuItems::NewFolder ); +} + +void LayerList::menuActivated( int id, LayerItem *layer ) +{ + const TQValueList<LayerItem*> selected = selectedLayers(); + + LayerItem *tqparent = ( layer && layer->isFolder() ) ? layer : 0; + LayerItem *after = 0; + if( layer && !tqparent ) + { + tqparent = layer->tqparent(); + after = layer->prevSibling(); + } + switch( id ) + { + case MenuItems::NewLayer: + emit requestNewLayer( tqparent, after ); + emit requestNewLayer( tqparent ? tqparent->id() : -1, after ? after->id() : -1 ); + break; + case MenuItems::NewFolder: + emit requestNewFolder( tqparent, after ); + emit requestNewFolder( tqparent ? tqparent->id() : -1, after ? after->id() : -1 ); + break; + case MenuItems::RemoveLayer: + { + TQValueList<int> ids; + for( int i = 0, n = selected.count(); i < n; ++i ) + { + ids.append( selected[i]->id() ); + emit requestRemoveLayer( selected[i]->id() ); + } + emit requestRemoveLayers( ids ); + } + for( int i = 0, n = selected.count(); i < n; ++i ) + emit requestRemoveLayer( selected[i] ); + emit requestRemoveLayers( selected ); + break; + case MenuItems::LayerProperties: + if( layer ) + { + emit requestLayerProperties( layer ); + emit requestLayerProperties( layer->id() ); + } + break; + default: + if( id >= MenuItems::COUNT && layer ) + for( int i = 0, n = selected.count(); i < n; ++i ) + selected[i]->toggleProperty( d->properties[ id - MenuItems::COUNT ].name ); + } +} + +void LayerList::slotItemRenamed( TQListViewItem *item, const TQString &text, int col ) +{ + if( !item || col != 0 ) + return; + + emit displayNameChanged( static_cast<LayerItem*>( item ), text ); + emit displayNameChanged( static_cast<LayerItem*>( item )->id(), text ); +} + +void LayerList::slotItemMoved( TQPtrList<TQListViewItem> &items, TQPtrList<TQListViewItem> &/*afterBefore*/, TQPtrList<TQListViewItem> &afterNow ) +{ + for( int i = 0, n = items.count(); i < n; ++i ) + { + LayerItem *l = static_cast<LayerItem*>( items.at(i) ), *a = static_cast<LayerItem*>( afterNow.at(i) ); + if( !l ) + continue; + + if( l->tqparent() ) + l->tqparent()->setOpen( true ); + + emit layerMoved( l, l->tqparent(), a ); + emit layerMoved( l->id(), l->tqparent() ? l->tqparent()->id() : -1, a ? a->id() : -1 ); + } +} + +void LayerList::setCurrentItem( TQListViewItem *item ) +{ + if( !item ) + return; + + super::setCurrentItem( item ); + ensureItemVisible( item ); + int n = 0; + for( LayerItemIterator it( this, LayerItemIterator::Selected ); n < 2 && (*it); ++it ) { n++; } + if( n == 1 ) + (*LayerItemIterator( this, LayerItemIterator::Selected ))->setSelected( false ); + item->setSelected( true ); + if( activeLayer() != item ) + setActiveLayer( static_cast<LayerItem*>(item) ); +} + + +/////////////// +// LayerItem // +/////////////// + +LayerItem::LayerItem( const TQString &displayName, LayerList *p, LayerItem *after, int id ) + : super( p, after ), d( new Private( id ) ) +{ + init(); + setDisplayName( displayName ); +} + +LayerItem::LayerItem( const TQString &displayName, LayerItem *p, LayerItem *after, int id ) + : super( ( p && p->isFolder() ) ? p : 0, after ), d( new Private( id ) ) +{ + init(); + setDisplayName( displayName ); +} + +void LayerItem::init() +{ + if( d->id < 0 ) + d->id = getID(); + + for( int i = 0, n = listView()->d->properties.count(); i < n; ++i ) + d->properties.append( listView()->d->properties[i].defaultValue ); + + if( tqparent()) + tqparent()->setOpen( true ); +} + +LayerItem::~LayerItem() +{ + if (listView() && (listView()->activeLayer() == this || tqcontains(listView()->activeLayer()))) + listView()->setActiveLayer( static_cast<LayerItem*>( 0 ) ); + delete d; +} + +void LayerItem::makeFolder() +{ + d->isFolder = true; + setPixmap( 0, SmallIcon( "folder", 16 ) ); + if( isActive() && !listView()->foldersCanBeActive() ) + listView()->setActiveLayer( static_cast<LayerItem*>( 0 ) ); +} + +bool LayerItem::isFolder() const +{ + return d->isFolder; +} + +bool LayerItem::tqcontains(const LayerItem *item) +{ + TQListViewItemIterator it(this); + + while (it.current()) { + if (static_cast<const LayerItem *>(it.current()) == item) { + return true; + } + ++it; + } + return false; +} + +int LayerItem::id() const +{ + return d->id; +} + +TQString LayerItem::displayName() const +{ + return text( 0 ); +} + +void LayerItem::setDisplayName( const TQString &s ) +{ + if( displayName() == s ) + return; + setText( 0, s ); + emit listView()->displayNameChanged( this, s ); + emit listView()->displayNameChanged( id(), s ); +} + +bool LayerItem::isActive() const +{ + return listView()->activeLayer() == this; +} + +void LayerItem::setActive() +{ + listView()->setActiveLayer( this ); +} + +bool LayerItem::property( const TQString &name ) const +{ + int i = listView()->d->properties.count() - 1; + while( i && listView()->d->properties[i].name != name ) + --i; + + if( i < 0 ) + return false; //should do something more severe... but what? + + return d->properties[i]; +} + +void LayerItem::setProperty( const TQString &name, bool on ) +{ + int i = listView()->d->properties.count() - 1; + while( i && listView()->d->properties[i].name != name ) + --i; + + if( i < 0 || ( isFolder() && !listView()->d->properties[i].validForFolders ) ) + return; + + const bool notify = ( on != d->properties[i] ); + d->properties[i] = on; + if( notify ) + { + emit listView()->propertyChanged( this, name, on ); + emit listView()->propertyChanged( id(), name, on ); + } + + update(); +} + +void LayerItem::toggleProperty( const TQString &name ) +{ + int i = listView()->d->properties.count() - 1; + while( i && listView()->d->properties[i].name != name ) + --i; + + if( i < 0 || ( isFolder() && !listView()->d->properties[i].validForFolders ) ) + return; + + d->properties[i] = !(d->properties[i]); + emit listView()->propertyChanged( this, name, d->properties[i] ); + emit listView()->propertyChanged( id(), name, d->properties[i] ); + + update(); +} + +void LayerItem::setPreviewImage( TQImage *image ) +{ + d->previewImage = image; + previewChanged(); +} + +void LayerItem::previewChanged() +{ + d->previewChanged = true; + update(); +} + +LayerItem *LayerItem::addLayer( const TQString &displayName, LayerItem *after, int id ) +{ + if( !isFolder() ) + return 0; + return new LayerItem( displayName, this, after, id ); +} + +LayerItem *LayerItem::prevSibling() const +{ + LayerItem *item = tqparent() ? tqparent()->firstChild() : listView()->firstChild(); + if( !item || this == item ) + return 0; + for(; item && this != item->nextSibling(); item = item->nextSibling() ); + return item; +} + +int LayerItem::mapXFromListView( int x ) const +{ + return x - rect().left(); +} + +int LayerItem::mapYFromListView( int y ) const +{ + return y - rect().top(); +} + +TQPoint LayerItem::mapFromListView( const TQPoint &point ) const +{ + return TQPoint( mapXFromListView( point.x() ), mapYFromListView( point.y() ) ); +} + +TQRect LayerItem::mapFromListView( const TQRect &rect ) const +{ + return TQRect( mapFromListView( rect.topLeft() ), rect.size() ); +} + +int LayerItem::mapXToListView( int x ) const +{ + return x + rect().left(); +} + +int LayerItem::mapYToListView( int y ) const +{ + return y + rect().top(); +} + +TQPoint LayerItem::mapToListView( const TQPoint &point ) const +{ + return TQPoint( mapXToListView( point.x() ), mapYToListView( point.y() ) ); +} + +TQRect LayerItem::mapToListView( const TQRect &rect ) const +{ + return TQRect( mapToListView( rect.topLeft() ), rect.size() ); +} + +TQRect LayerItem::rect() const +{ + const int indent = listView()->treeStepSize() * ( depth() + 1 ); + return TQRect( listView()->header()->sectionPos( 0 ) + indent, itemPos(), + listView()->header()->sectionSize( 0 ) - indent, height() ); +} + +TQRect LayerItem::textRect() const +{ + static TQFont f; + static int minbearing = 1337 + 666; //can be 0 or negative, 2003 is less likely + if( minbearing == 2003 || f != font() ) + { + f = font(); //getting your bearings can be expensive, so we cache them + minbearing = fontMetrics().minLeftBearing() + fontMetrics().minRightBearing(); + } + + const int margin = listView()->itemMargin(); + int indent = previewRect().right() + margin; + if( pixmap( 0 ) ) + indent += pixmap( 0 )->width() + margin; + + const int width = ( multiline() ? rect().right() : iconsRect().left() ) - indent - margin + minbearing; + + return TQRect( indent, 0, width, fontMetrics().height() ); +} + +TQRect LayerItem::iconsRect() const +{ + const TQValueList<LayerProperty> &lp = listView()->d->properties; + int propscount = 0; + for( int i = 0, n = lp.count(); i < n; ++i ) + if( !lp[i].enabledIcon.isNull() && ( !multiline() || !isFolder() || lp[i].validForFolders ) ) + propscount++; + + const int iconswidth = propscount * iconSize().width() + (propscount - 1) * listView()->itemMargin(); + + const int x = multiline() ? previewRect().right() + listView()->itemMargin() : rect().width() - iconswidth; + const int y = multiline() ? fontMetrics().height() : 0; + + return TQRect( x, y, iconswidth, iconSize().height() ); +} + +TQRect LayerItem::previewRect() const +{ + return TQRect( 0, 0, listView()->previewsShown() ? height() : 0, height() ); +} + +void LayerItem::drawText( TQPainter *p, const TQColorGroup &cg, const TQRect &r ) +{ + p->translate( r.left(), r.top() ); + + p->setPen( isSelected() ? cg.highlightedText() : cg.text() ); + + const TQString text = KStringHandler::rPixelSqueeze( displayName(), p->fontMetrics(), r.width() ); + p->drawText( listView()->itemMargin(), 0, r.width(), r.height(), TQt::AlignAuto | TQt::AlignTop, text ); + + p->translate( -r.left(), -r.top() ); +} + +void LayerItem::drawIcons( TQPainter *p, const TQColorGroup &/*cg*/, const TQRect &r ) +{ + p->translate( r.left(), r.top() ); + + int x = 0; + const TQValueList<LayerProperty> &lp = listView()->d->properties; + for( int i = 0, n = lp.count(); i < n; ++i ) + if( !lp[i].enabledIcon.isNull() && ( !multiline() || !isFolder() || lp[i].validForFolders ) ) + { + if( !isFolder() || lp[i].validForFolders ) + p->drawPixmap( x, 0, d->properties[i] ? lp[i].enabledIcon : lp[i].disabledIcon ); + x += iconSize().width() + listView()->itemMargin(); + } + + p->translate( -r.left(), -r.top() ); +} + +void LayerItem::drawPreview( TQPainter *p, const TQColorGroup &/*cg*/, const TQRect &r ) +{ + if( !showPreview() ) + return; + + if( d->previewChanged || r.size() != d->previewSize ) + { //TODO handle width() != height() + const int size = kMin( r.width(), kMax( previewImage()->width(), previewImage()->height() ) ); + const TQImage i = previewImage()->smoothScale( size, size, TQ_ScaleMin ); + d->scaledPreview.convertFromImage( i ); + d->previewOffset.setX( r.width()/2 - i.width()/2 ); + d->previewOffset.setY( r.height()/2 - i.height()/2 ); + + d->previewChanged = false; + d->previewSize = r.size(); + } + + p->drawPixmap( r.topLeft() + d->previewOffset, d->scaledPreview ); +} + +bool LayerItem::showPreview() const +{ + return listView()->previewsShown() && previewImage() && !previewImage()->isNull(); +} + +bool LayerItem::multiline() const +{ + return height() >= fontMetrics().height() + iconSize().height(); +} + +TQFont LayerItem::font() const +{ + if( isActive() ) + { + TQFont f = listView()->font(); + f.setBold( !f.bold() ); + f.setItalic( !f.italic() ); + return f; + } + else + return listView()->font(); +} + +TQFontMetrics LayerItem::fontMetrics() const +{ + return TQFontMetrics( font() ); +} + +bool LayerItem::mousePressEvent( TQMouseEvent *e ) +{ + if( e->button() == Qt::RightButton ) + { + if ( !(e->state() & TQt::ControlButton) && !(e->state() & TQt::ShiftButton) ) + setActive(); + TQTimer::singleShot( 0, listView(), TQT_SLOT( showContextMenu() ) ); + return false; + } + + const TQRect ir = iconsRect(), tr = textRect(); + + if( ir.tqcontains( e->pos() ) ) + { + const int iconWidth = iconSize().width(); + int x = e->pos().x() - ir.left(); + if( x % ( iconWidth + listView()->itemMargin() ) < iconWidth ) //it's on an icon, not a margin + { + const TQValueList<LayerProperty> &lp = listView()->d->properties; + int p = -1; + for( int i = 0, n = lp.count(); i < n; ++i ) + { + if( !lp[i].enabledIcon.isNull() && ( !multiline() || !isFolder() || lp[i].validForFolders ) ) + x -= iconWidth + listView()->itemMargin(); + p += 1; + if( x < 0 ) + break; + } + toggleProperty( lp[p].name ); + } + return true; + } + + else if( tr.tqcontains( e->pos() ) && isSelected() && !listView()->renameLineEdit()->isVisible() ) + { + listView()->rename( this, 0 ); + TQRect r( listView()->contentsToViewport( mapToListView( tr.topLeft() ) ), tr.size() ); + listView()->renameLineEdit()->setGeometry( r ); + return true; + } + + if ( !(e->state() & TQt::ControlButton) && !(e->state() & TQt::ShiftButton) ) + setActive(); + + return false; +} + +TQString LayerItem::tooltip() const +{ + TQString tip; + tip += "<table cellspacing=\"0\" cellpadding=\"0\">"; + tip += TQString("<tr><td colspan=\"2\" align=\"center\"><b>%1</b></td></tr>").tqarg( displayName() ); + TQString row = "<tr><td>%1</td><td>%2</td></tr>"; + for( int i = 0, n = listView()->d->properties.count(); i < n; ++i ) + if( !isFolder() || listView()->d->properties[i].validForFolders ) + { + if( d->properties[i] ) + tip += row.tqarg( i18n( "%1:" ).tqarg( listView()->d->properties[i].displayName ) ).tqarg( i18n( "Yes" ) ); + else + tip += row.tqarg( i18n( "%1:" ).tqarg( listView()->d->properties[i].displayName ) ).tqarg( i18n( "No" ) ); + } + tip += "</table>"; + return tip; +} + +TQImage *LayerItem::previewImage() const +{ + return d->previewImage; +} + +TQImage LayerItem::tooltipPreview() const +{ + if( previewImage() ) + return *previewImage(); + return TQImage(); +} + +int LayerItem::width( const TQFontMetrics &fm, const TQListView *lv, int c ) const +{ + if( c != 0 ) + return super::width( fm, lv, c ); + + const TQValueList<LayerProperty> &lp = listView()->d->properties; + int propscount = 0; + for( int i = 0, n = d->properties.count(); i < n; ++i ) + if( !lp[i].enabledIcon.isNull() && ( !multiline() || !isFolder() || lp[i].validForFolders ) ) + propscount++; + + const int iconswidth = propscount * iconSize().width() + (propscount - 1) * listView()->itemMargin(); + + if( multiline() ) + return kMax( super::width( fm, lv, 0 ), iconswidth ); + else + return super::width( fm, lv, 0 ) + iconswidth; +} + +void LayerItem::paintCell( TQPainter *painter, const TQColorGroup &cg, int column, int width, int align ) +{ + if( column != 0 ) + { + super::paintCell( painter, cg, column, width, align ); + return; + } + + TQPixmap buf( width, height() ); + TQPainter p( &buf ); + + p.setFont( font() ); + + const TQColorGroup cg_ = isEnabled() ? listView()->tqpalette().active() : listView()->tqpalette().disabled(); + + const TQColor bg = isSelected() ? cg_.highlight() + : isAlternate() ? listView()->alternateBackground() + : listView()->viewport()->backgroundColor(); + + buf.fill( bg ); + + if( pixmap( 0 ) ) + p.drawPixmap( previewRect().right() + listView()->itemMargin(), 0, *pixmap( 0 ) ); + + drawText( &p, cg_, textRect() ); + drawIcons( &p, cg_, iconsRect() ); + drawPreview( &p, cg_, previewRect() ); + + painter->drawPixmap( 0, 0, buf ); +} + +void LayerItem::setup() +{ + super::setup(); + setHeight( listView()->d->itemHeight ); +} + +void LayerItem::setSelected( bool selected ) +{ + if( !selected && ( isActive() || this == listView()->currentItem() ) ) + return; + super::setSelected( selected ); +} + + +///////////////////////// +// Convenience Methods // +///////////////////////// + +LayerItem *LayerList::firstChild() const { return static_cast<LayerItem*>( super::firstChild() ); } +LayerItem *LayerList::lastChild() const { return static_cast<LayerItem*>( super::lastChild() ); } +LayerList *LayerItem::listView() const { return static_cast<LayerList*>( super::listView() ); } +void LayerItem::update() const { listView()->tqrepaintItem( this ); } +LayerItem *LayerItem::firstChild() const { return static_cast<LayerItem*>( super::firstChild() ); } +LayerItem *LayerItem::nextSibling() const { return static_cast<LayerItem*>( super::nextSibling() ); } +LayerItem *LayerItem::tqparent() const { return static_cast<LayerItem*>( super::tqparent() ); } + + +#include "layerlist.moc" diff --git a/chalk/ui/layerlist.h b/chalk/ui/layerlist.h new file mode 100644 index 00000000..129baa7c --- /dev/null +++ b/chalk/ui/layerlist.h @@ -0,0 +1,269 @@ +/* + Copyright (c) 2005 Gábor Lehel <illissius@gmail.com> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + + +#ifndef LAYERLIST_H +#define LAYERLIST_H + +#include <tqiconset.h> +#include <klistview.h> + +class TQMouseEvent; +class TQString; +class KPopupMenu; +class LayerItem; +class LayerFolder; +template<class T> class TQPtrList; + +class LayerList: public KListView +{ + Q_OBJECT + TQ_OBJECT + +public: + LayerList( TQWidget *tqparent = 0, const char *name = 0 ); + virtual ~LayerList(); + + void addProperty( const TQString &name, const TQString &displayName, const TQIconSet &icon = TQIconSet(), + bool defaultValue = false, bool validForFolders = true ); + void addProperty( const TQString &name, const TQString &displayName, TQPixmap enabled, TQPixmap disabled, + bool defaultValue = false, bool validForFolders = true ); + + bool foldersCanBeActive() const; + bool previewsShown() const; + int itemHeight() const; + int numRows() const; + + LayerItem *layer( int id ) const; + LayerItem *folder( int id ) const; //returns 0 if not a folder + + LayerItem *activeLayer() const; + int activeLayerID() const; + + TQValueList<LayerItem*> selectedLayers() const; + TQValueList<int> selectedLayerIDs() const; + + void makeFolder( int id ); + bool isFolder( int id ) const; + TQString displayName( int id ) const; + bool property( int id, const TQString &name ) const; + + struct MenuItems + { + enum { NewLayer = 0, NewFolder, RemoveLayer, LayerProperties, COUNT }; + }; + KPopupMenu *contextMenu() const; + +public slots: + void setFoldersCanBeActive( bool can ); + void setPreviewsShown( bool show ); + void setItemHeight( int height ); + void setNumRows( int rows ); //how many rows of property icons can fit + + void setActiveLayer( LayerItem *layer ); + void setActiveLayer( int id ); + + void setLayerDisplayName( LayerItem *layer, const TQString &displayName ); + void setLayerDisplayName( int id, const TQString &displayName ); + + void setLayerProperty( LayerItem *layer, const TQString &name, bool on ); + void setLayerProperty( int id, const TQString &name, bool on ); + + void toggleLayerProperty( LayerItem *layer, const TQString &name ); + void toggleLayerProperty( int id, const TQString &name ); + + void setLayerPreviewImage( LayerItem *layer, TQImage *image ); + void setLayerPreviewImage( int id, TQImage *image ); + + void layerPreviewChanged( LayerItem *layer ); + void layerPreviewChanged( int id ); + + LayerItem *addLayer( const TQString &displayName, LayerItem *after = 0, int id = -1 ); + LayerItem *addLayer( const TQString &displayName, int afterID, int id = -1 ); + + LayerItem *addLayerToParent( const TQString &displayName, LayerItem *tqparent, LayerItem *after = 0, int id = -1 ); + LayerItem *addLayerToParent( const TQString &displayName, int tqparentID, int afterID = -1, int id = -1 ); + + void moveLayer( LayerItem *layer, LayerItem *tqparent, LayerItem *after ); + void moveLayer( int id, int tqparentID, int afterID ); + + void removeLayer( LayerItem *layer ); + void removeLayer( int id ); + +signals: + void activated( LayerItem *layer ); + void activated( int id ); + + void displayNameChanged( LayerItem *layer, const TQString &displayName ); + void displayNameChanged( int id, const TQString &displayName ); + + void propertyChanged( LayerItem *layer, const TQString &name, bool on ); + void propertyChanged( int id, const TQString &name, bool on ); + + void layerMoved( LayerItem *layer, LayerItem *tqparent, LayerItem *after ); + void layerMoved( int id, int tqparentID, int afterID ); + + void requestNewLayer( LayerItem *tqparent, LayerItem *after ); + void requestNewLayer( int tqparentID, int afterID ); + + void requestNewFolder( LayerItem *tqparent, LayerItem *after ); + void requestNewFolder( int tqparentID, int afterID ); + + void requestRemoveLayer( LayerItem *layer ); + void requestRemoveLayer( int id ); + + void requestRemoveLayers( TQValueList<LayerItem*> layers ); + void requestRemoveLayers( TQValueList<int> ids ); + + void requestLayerProperties( LayerItem *layer ); + void requestLayerProperties( int id ); + +public: //convenience + LayerItem *firstChild() const; + LayerItem *lastChild() const; + +protected slots: + virtual void constructMenu( LayerItem *layer ); + virtual void menuActivated( int id, LayerItem *layer ); + +private: + typedef KListView super; + friend class LayerItem; + friend class LayerToolTIp; + + class Private; + Private* const d; + +private slots: + void slotItemRenamed( TQListViewItem *item, const TQString &text, int col ); + void slotItemMoved( TQPtrList<TQListViewItem>&, TQPtrList<TQListViewItem>&, TQPtrList<TQListViewItem>& ); + void showContextMenu(); + void hideTip(); + void maybeTip(); + +public: //reimplemented for internal reasons + virtual void setCurrentItem( TQListViewItem *i ); + +protected: + virtual void contentsMousePressEvent( TQMouseEvent *e ); + virtual void contentsMouseDoubleClickEvent ( TQMouseEvent *e ); + virtual void findDrop( const TQPoint &pos, TQListViewItem *&tqparent, TQListViewItem *&after ); +}; + +class LayerItem: public KListViewItem +{ +public: + LayerItem( const TQString &displayName, LayerList *tqparent, LayerItem *after = 0, int id = -1 ); + LayerItem( const TQString &displayName, LayerItem *tqparent, LayerItem *after = 0, int id = -1 ); + virtual ~LayerItem(); + + void makeFolder(); + bool isFolder() const; + + // Returns true if this item is the given item or the tree rooted at + // this item contains the given item. + bool tqcontains(const LayerItem *item); + + int id() const; + + TQString displayName() const; + void setDisplayName( const TQString &displayName ); + + bool isActive() const; + void setActive(); + + bool property( const TQString &name ) const; + void setProperty( const TQString &name, bool on ); + void toggleProperty( const TQString &name ); + + void setPreviewImage( TQImage *image ); + void previewChanged(); + + LayerItem *addLayer( const TQString &displayName, LayerItem *after = 0, int id = -1 ); + + LayerItem *prevSibling() const; + +public: //convenience + LayerItem *nextSibling() const; + LayerList *listView() const; + LayerItem *firstChild() const; + LayerItem *tqparent() const; + void update() const; //like TQWidget::update() + +protected: + virtual TQRect rect() const; + + int mapXFromListView( int x ) const; + int mapYFromListView( int y ) const; + TQPoint mapFromListView( const TQPoint &point ) const; + TQRect mapFromListView( const TQRect &rect ) const; + + int mapXToListView( int x ) const; + int mapYToListView( int y ) const; + TQPoint mapToListView( const TQPoint &point ) const; + TQRect mapToListView( const TQRect &rect ) const; + + virtual TQRect textRect() const; + virtual TQRect iconsRect() const; + virtual TQRect previewRect() const; + + virtual void drawText( TQPainter *p, const TQColorGroup &cg, const TQRect &r ); + virtual void drawIcons( TQPainter *p, const TQColorGroup &cg, const TQRect &r ); + virtual void drawPreview( TQPainter *p, const TQColorGroup &cg, const TQRect &r ); + + bool multiline() const; + bool showPreview() const; + virtual TQFont font() const; + TQFontMetrics fontMetrics() const; + + virtual bool mousePressEvent( TQMouseEvent *e ); + + virtual TQString tooltip() const; + + virtual TQImage *previewImage() const; + virtual TQImage tooltipPreview() const; + +private: + typedef KListViewItem super; + friend class LayerList; + friend class LayerToolTip; + + class Private; + Private* const d; + + void init(); + +public: //reimplemented for internal reasons + virtual int width( const TQFontMetrics &fm, const TQListView *lv, int c ) const; + virtual void paintCell( TQPainter *p, const TQColorGroup &cg, int column, int width, int align ); + virtual void setup(); + virtual void setSelected( bool selected ); +}; + +class LayerFolder: public LayerItem +{ +public: + LayerFolder( const TQString &displayName, LayerList *tqparent, LayerItem *after = 0, int id = -1 ) + : LayerItem( displayName, tqparent, after, id ) { makeFolder(); } + LayerFolder( const TQString &displayName, LayerItem *tqparent, LayerItem *after = 0, int id = -1 ) + : LayerItem( displayName, tqparent, after, id ) { makeFolder(); } +}; + + +#endif diff --git a/chalk/ui/squeezedcombobox.cpp b/chalk/ui/squeezedcombobox.cpp new file mode 100644 index 00000000..96929450 --- /dev/null +++ b/chalk/ui/squeezedcombobox.cpp @@ -0,0 +1,167 @@ +/* ============================================================ + * Author: Tom Albers <tomalbers@kde.nl> + * Date : 2005-01-01 + * Description : + * + * Copyright 2005 by Tom Albers + * + * 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 2, 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. + * + * ============================================================ */ + +/** @file squeezedcombobox.cpp */ + +// TQt includes. + +#include <tqlistbox.h> +#include <tqcombobox.h> +#include <tqpair.h> +#include <tqtimer.h> +#include <tqvaluelist.h> +#include <tqstyle.h> +#include <tqapplication.h> +#include <tqtooltip.h> + +// Local includes. + +#include "squeezedcombobox.h" + +SqueezedComboBoxTip::SqueezedComboBoxTip( TQWidget * tqparent, SqueezedComboBox* name ) + : TQToolTip( tqparent ) +{ + m_originalWidget = name; +} + +void SqueezedComboBoxTip::maybeTip( const TQPoint &pos ) +{ + TQListBox* listBox = m_originalWidget->listBox(); + if (!listBox) + return; + + TQListBoxItem* selectedItem = listBox->itemAt( pos ); + if (selectedItem) + { + TQRect positionToolTip = listBox->tqitemRect( selectedItem ); + TQString toolTipText = m_originalWidget->itemHighlighted(); + if (!toolTipText.isNull()) + tip(positionToolTip, toolTipText); + } +} + +SqueezedComboBox::SqueezedComboBox( TQWidget *tqparent, const char *name ) + : TQComboBox( tqparent, name ) +{ + setMinimumWidth(100); + m_timer = new TQTimer(this); + m_tooltip = new SqueezedComboBoxTip( listBox()->viewport(), this ); + + connect(m_timer, TQT_SIGNAL(timeout()), + TQT_SLOT(slotTimeOut())); + connect(this, TQT_SIGNAL(activated( int )), + TQT_SLOT(slotUpdateToolTip( int ))); +} + +SqueezedComboBox::~SqueezedComboBox() +{ + delete m_tooltip; + delete m_timer; +} + +bool SqueezedComboBox::tqcontains( const TQString& _text ) const +{ + if ( _text.isEmpty() ) + return false; + + const int itemCount = count(); + for (int i = 0; i < itemCount; ++i ) + { + if ( text(i) == _text ) + return true; + } + return false; +} + +TQSize SqueezedComboBox::tqsizeHint() const +{ + constPolish(); + TQFontMetrics fm = fontMetrics(); + + int maxW = count() ? 18 : 7 * fm.width(TQChar('x')) + 18; + int maxH = TQMAX( fm.lineSpacing(), 14 ) + 2; + + return tqstyle().tqsizeFromContents(TQStyle::CT_ComboBox, this, + TQSize(maxW, maxH)). + expandedTo(TQApplication::globalStrut()); +} + +void SqueezedComboBox::insertSqueezedItem(const TQString& newItem, int index) +{ + m_originalItems[index] = newItem; + insertItem( squeezeText(newItem), index ); + + // if this is the first item, set the tooltip. + if (index == 0) + slotUpdateToolTip(0); +} + +void SqueezedComboBox::resizeEvent ( TQResizeEvent * ) +{ + m_timer->start(200, true); +} + +void SqueezedComboBox::slotTimeOut() +{ + TQMapIterator<int,TQString> it; + for (it = m_originalItems.begin() ; it != m_originalItems.end(); + ++it) + { + changeItem( squeezeText( it.data() ), it.key() ); + } +} + +TQString SqueezedComboBox::squeezeText( const TQString& original) +{ + // not the complete widgetSize is usable. Need to compensate for that. + int widgetSize = width()-30; + TQFontMetrics fm( fontMetrics() ); + + // If we can fit the full text, return that. + if (fm.width(original) < widgetSize) + return(original); + + // We need to squeeze. + TQString sqItem = original; // prevent empty return value; + widgetSize = widgetSize-fm.width("..."); + for (uint i = 0 ; i != original.length(); ++i) + { + if ( (int)fm.width(original.right(i)) > widgetSize) + { + sqItem = TQString("..." + original.right(--i)); + break; + } + } + return sqItem; +} + +void SqueezedComboBox::slotUpdateToolTip( int index ) +{ + TQToolTip::remove(this); + TQToolTip::add(this, m_originalItems[index]); +} + +TQString SqueezedComboBox::itemHighlighted() +{ + int curItem = this->listBox()->currentItem(); + return m_originalItems[curItem]; +} + +#include "squeezedcombobox.moc" diff --git a/chalk/ui/squeezedcombobox.h b/chalk/ui/squeezedcombobox.h new file mode 100644 index 00000000..66758335 --- /dev/null +++ b/chalk/ui/squeezedcombobox.h @@ -0,0 +1,137 @@ +/* ============================================================ + * Author: Tom Albers <tomalbers@kde.nl> + * Date : 2005-01-01 + * Description : + * + * Copyright 2005 by Tom Albers + * + * 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 2, 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. + * + * ============================================================ */ + +/** @file squeezedcombobox.h */ + +#ifndef STQUEEZEDCOMBOBOX_H +#define STQUEEZEDCOMBOBOX_H + +class TQTimer; + +// TQt includes. + +#include <tqcombobox.h> +#include <tqtooltip.h> + +class SqueezedComboBox; + +/** @class SqueezedComboBoxTip + * This class shows a tooltip for a SqueezedComboBox + * the tooltip will contain the full text and helps + * the user find the correct entry. It is automatically + * activated when starting a SqueezedComboBox. This is + * inherited from TQToolTip + * + * @author Tom Albers + */ +class SqueezedComboBoxTip : public TQToolTip +{ +public: + /** + * Constructor. An example call (as done in + * SqueezedComboBox::SqueezedComboBox): + * @code + * t = new SqueezedComboBoxTip( this->listBox()->viewport(), this ); + * @endcode + * + * @param tqparent tqparent widget (viewport) + * @param name tqparent widget + */ + SqueezedComboBoxTip( TQWidget *tqparent, SqueezedComboBox *name ); + +protected: + /** + * Reimplemented version from TQToolTip which shows the + * tooltip when needed. + * @param pos the point where the mouse currently is + */ + void maybeTip( const TQPoint& pos ); + +private: + SqueezedComboBox* m_originalWidget; +}; + +/** @class SqueezedComboBox + * + * This widget is a TQComboBox, but then a little bit + * different. It only shows the right part of the items + * depending on de size of the widget. When it is not + * possible to show the complete item, it will be shortened + * and "..." will be prepended. + * + * @image html squeezedcombobox.png "This is how it looks" + * @author Tom Albers + */ +class SqueezedComboBox : public TQComboBox +{ + Q_OBJECT + TQ_OBJECT + +public: + /** + * Constructor + * @param tqparent tqparent widget + * @param name name to give to the widget + */ + SqueezedComboBox(TQWidget *tqparent = 0, const char *name = 0 ); + + /** + * destructor + */ + virtual ~SqueezedComboBox(); + + bool tqcontains(const TQString & text) const; + + /** + * This inserts a item to the list. See TQComboBox::insertItem() + * for detaills. Please do not use TQComboBox::insertItem() to this + * widget, as that will fail. + * @param newItem the original (long version) of the item which needs + * to be added to the combobox + * @param index the position in the widget. + */ + void insertSqueezedItem(const TQString& newItem, int index); + + /** + * This method returns the full text (not squeezed) of the currently + * highlighted item. + * @return full text of the highlighted item + */ + TQString itemHighlighted( ); + + /** + * Sets the tqsizeHint() of this widget. + */ + virtual TQSize tqsizeHint() const; + +private slots: + void slotTimeOut(); + void slotUpdateToolTip( int index ); + +private: + void resizeEvent ( TQResizeEvent * ); + TQString squeezeText( const TQString& original); + + TQMap<int,TQString> m_originalItems; + TQTimer* m_timer; + SqueezedComboBoxTip* m_tooltip; +}; + +#endif // STQUEEZEDCOMBOBOX_H diff --git a/chalk/ui/wdgapplyprofile.ui b/chalk/ui/wdgapplyprofile.ui new file mode 100644 index 00000000..35674162 --- /dev/null +++ b/chalk/ui/wdgapplyprofile.ui @@ -0,0 +1,172 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>WdgApplyProfile</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>WdgApplyProfile</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>538</width> + <height>312</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQGroupBox" row="0" column="0"> + <property name="name"> + <cstring>groupBox1</cstring> + </property> + <property name="title"> + <string>Apply Profile</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="1" column="0"> + <property name="name"> + <cstring>lblProfile</cstring> + </property> + <property name="text"> + <string>&Profiles:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cmbProfile</cstring> + </property> + </widget> + <widget class="SqueezedComboBox" row="1" column="1"> + <item> + <property name="text"> + <string>None</string> + </property> + </item> + <property name="name"> + <cstring>cmbProfile</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + <widget class="TQLabel" row="0" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>The image data you want to paste does not have an ICM profile associated with it. If you do not select a profile, Chalk will assume that the image data is encoded in the import profile defined in the Settings dialog.</string> + </property> + <property name="tqalignment"> + <set>WordBreak|AlignVCenter</set> + </property> + </widget> + <widget class="TQButtonGroup" row="2" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>grpRenderIntent</cstring> + </property> + <property name="title"> + <string>&Rendering Intent</string> + </property> + <property name="toolTip" stdset="0"> + <string></string> + </property> + <property name="whatsThis" stdset="0"> + <string>Rendering intent determines the bias in the color conversion.</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQRadioButton" row="1" column="0"> + <property name="name"> + <cstring>radioRelativeColorimetric</cstring> + </property> + <property name="text"> + <string>Relative colorimetric</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Within and outside gamut; same as Absolute Colorimetric. White point changed to result in neutral grays.</string> + </property> + </widget> + <widget class="TQRadioButton" row="2" column="0"> + <property name="name"> + <cstring>radioSaturation</cstring> + </property> + <property name="text"> + <string>Saturation</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Hue and saturation maintained with lightness sacrificed to maintain saturation. White point changed to result in neutral grays. Intended for business graphics (make it colorful charts, graphs, overheads, ...)</string> + </property> + </widget> + <widget class="TQRadioButton" row="3" column="0"> + <property name="name"> + <cstring>radioButton4</cstring> + </property> + <property name="text"> + <string>Absolute colorimetric</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Within the destination device gamut; hue, lightness and saturation are maintained. Outside the gamut; hue and lightness are maintained, saturation is sacrificed. White point for source and destination; unchanged. Intended for spot colors (Pantone, TruMatch, logo colors, ...)</string> + </property> + </widget> + <widget class="TQRadioButton" row="0" column="0"> + <property name="name"> + <cstring>radioPerceptual</cstring> + </property> + <property name="text"> + <string>Perceptual</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Hue hopefully maintained (but not required), lightness and saturation sacrificed to maintain the perceived color. White point changed to result in neutral grays. Intended for images.</string> + </property> + </widget> + </grid> + </widget> + </grid> + </widget> + </grid> +</widget> +<customwidgets> + <customwidget> + <class>SqueezedComboBox</class> + <header location="local">squeezedcombobox.h</header> + <sizehint> + <width>-1</width> + <height>i24</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>3</hordata> + <verdata>0</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image0</pixmap> + </customwidget> +</customwidgets> +<images> + <image name="image0"> + <data format="PNG" length="870">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000032d49444154388db59531681c4714863f892dde8004b320c32e3870020b74458a6b0f5458e581c016a809a8496b42208454098604d2c4904a6954a410511ae752085b858c1208dc35221244b00119f60ac12ee860062c980719708a95a248f129459cd7cceeccf0edb76fff61a706830197d5ed765ff3166a30184c4d5d829fed3c7bdd5e6ce3bda71a5738ef301802e1d6d179477152303c1842bc822797a64fbf7b4a9a43be00ada817cb0e12011c2611205ccd73755f9c087c6b19bef0d7c100f5b8267d07caf10fe8ab9210156320fc01be16aa5a11043307f30b20a21041019985f48ef2f7fa0becc68e80475fd584e831b396f210f67795c3831a4940a3228925bb27f4d652ba4b01a199b73342f3981be0ca57745042ac30c632d853b6373d44b056c8ef0922508d94d14be59b2f4aeaf58cd5751069e06f3436890114332b9487d0bf80f61e64dc5f813c3790045453f67703fd4d4f7f6b4496b5597e689044af194f5f5e841800210478bee3d1a8f41e64acbe0f69ae6852e1cf0ccf7f74f4d652defbc042226c6f55e8f89f91bb6e9c387c9d521c9558db988a3416fe3c67e32b4779ec7167f0e8939ce19ea7fc5d298a80c875f03563930855ed2081bc05e91d5014ef53363eaf288e3d6285ee520a338e76c7a251a94e41e30470d3631004a262672e3eca59cec6978ef2b889979d11f2bb904af3be92081a416e28dfe831983920b1142345d5b0ff2234a6334276d7321ad53c795c511ca654a5a251996f19b83d158ef602b45a423d52f67703abeb29ee4ce9de4fc93378f218462f6b3efdb042cf3d59666977a0aa6fe9310888d25b13342afd4dcffeaee3d147399da540ab13f8f8b39c2cb3f8710d11ba2b96f9c57fcd7180287497a03ecde86f8dd8fe1a867b9ef6bb1612a84a871f6bd35b94e217a53832589970f2dcd85d9c7d4580d57521cbdaf4bfaf288e95e268d4ec8e60e72ccb0f2dbffea454e71e8d29f57882717152509482a48d8924b0bc12e82ee51445a03a6da079cbd0eec0fc22142b06620e89a3fc8d3783870743d814d2bc8994aa6ff286472e764902e5a96f72bbd3b4c37b280e95aa9e604c84e1cf978b37c74935797d7ae2ca7fac6968fe51ff0bf86dc30783c1d49f0baa9bb819e612310000000049454e44ae426082</data> + </image> +</images> +<tabstops> + <tabstop>cmbProfile</tabstop> +</tabstops> +<tqlayoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/chalk/ui/wdgautobrush.ui b/chalk/ui/wdgautobrush.ui new file mode 100644 index 00000000..a8aa02e0 --- /dev/null +++ b/chalk/ui/wdgautobrush.ui @@ -0,0 +1,355 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>KisWdgAutobrush</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>KisWdgAutobrush</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>373</width> + <height>200</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>1</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget" row="0" column="1"> + <property name="name"> + <cstring>tqlayout3</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQGroupBox"> + <property name="name"> + <cstring>grpSize</cstring> + </property> + <property name="title"> + <string>&Size</string> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="spacing"> + <number>0</number> + </property> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout21</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="spacing"> + <number>0</number> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>1</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>image0</pixmap> + </property> + </widget> + <widget class="TQSpinBox" row="0" column="1"> + <property name="name"> + <cstring>spinBoxWidth</cstring> + </property> + <property name="focusPolicy"> + <enum>ClickFocus</enum> + </property> + <property name="maxValue"> + <number>9999</number> + </property> + <property name="value"> + <number>5</number> + </property> + </widget> + <widget class="TQLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel2_2</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>image1</pixmap> + </property> + </widget> + <widget class="TQSpinBox" row="1" column="1"> + <property name="name"> + <cstring>spinBoxHeigth</cstring> + </property> + <property name="focusPolicy"> + <enum>ClickFocus</enum> + </property> + <property name="maxValue"> + <number>9999</number> + </property> + <property name="value"> + <number>5</number> + </property> + </widget> + </grid> + </widget> + <widget class="TQToolButton"> + <property name="name"> + <cstring>bnLinkSize</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="tqminimumSize"> + <size> + <width>16</width> + <height>0</height> + </size> + </property> + <property name="tqmaximumSize"> + <size> + <width>16</width> + <height>32767</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + <property name="toggleButton"> + <bool>true</bool> + </property> + <property name="on"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + <widget class="TQGroupBox"> + <property name="name"> + <cstring>grpFade</cstring> + </property> + <property name="title"> + <string>&Fade</string> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="spacing"> + <number>0</number> + </property> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout23</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="spacing"> + <number>0</number> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabelHorizontal</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>image0</pixmap> + </property> + </widget> + <widget class="TQSpinBox" row="0" column="1"> + <property name="name"> + <cstring>spinBoxHorizontal</cstring> + </property> + <property name="focusPolicy"> + <enum>ClickFocus</enum> + </property> + <property name="maxValue"> + <number>9999</number> + </property> + <property name="value"> + <number>1</number> + </property> + </widget> + <widget class="TQLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel2_2_2</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>image1</pixmap> + </property> + </widget> + <widget class="TQSpinBox" row="1" column="1"> + <property name="name"> + <cstring>spinBoxVertical</cstring> + </property> + <property name="focusPolicy"> + <enum>ClickFocus</enum> + </property> + <property name="maxValue"> + <number>9999</number> + </property> + <property name="value"> + <number>1</number> + </property> + </widget> + </grid> + </widget> + <widget class="TQToolButton"> + <property name="name"> + <cstring>bnLinkFade</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="tqminimumSize"> + <size> + <width>16</width> + <height>0</height> + </size> + </property> + <property name="tqmaximumSize"> + <size> + <width>16</width> + <height>32767</height> + </size> + </property> + <property name="backgroundMode"> + <enum>NoBackground</enum> + </property> + <property name="text"> + <string></string> + </property> + <property name="toggleButton"> + <bool>true</bool> + </property> + <property name="on"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + </vbox> + </widget> + <widget class="TQLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>tqlayout6</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQToolButton"> + <property name="name"> + <cstring>brushPreview</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="tqminimumSize"> + <size> + <width>95</width> + <height>95</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + <property name="usesBigPixmap"> + <bool>true</bool> + </property> + </widget> + <widget class="TQComboBox"> + <item> + <property name="text"> + <string>Circle</string> + </property> + </item> + <item> + <property name="text"> + <string>Square</string> + </property> + </item> + <property name="name"> + <cstring>comboBoxShape</cstring> + </property> + <property name="focusPolicy"> + <enum>ClickFocus</enum> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer4</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>20</width> + <height>0</height> + </size> + </property> + </spacer> + </vbox> + </widget> + </grid> +</widget> +<images> + <image name="image0"> + <data format="PNG" length="236">89504e470d0a1a0a0000000d49484452000000190000001a0806000000427df7cd000000b3494441544889dd963112c420084581d97acdfd4f29b9005b3913135050d722bf54f0018223e6ccf06f7db4c594be4d27e63304a190f525885e20154433f646ea050d6512d516887af10075c922f5d7e4ca24da4d439059f803721c4946a1962f798c6641d4da5c05421101445c06b82a6746804d73822202cc67956289a0c89a937b77596790b638abfb59d4da5c017840664196aff97679deab62d39bfcf73cf5ef8160ef4bb4e2e7627657e4909eb694eb071e3b4da9ba4f1ddb0000000049454e44ae426082</data> + </image> + <image name="image1"> + <data format="PNG" length="242">89504e470d0a1a0a0000000d49484452000000190000001a0806000000427df7cd000000b9494441544889dd95410ec4200845b1e9ba78ff538a176056260c5181569bccfca590ff2a204da510ecd601008078ed8778953372cec8db20d23c0a72417aa611900999997941a795500a256d2acf7a434354bf212d4927ebc488a417518d4dd75d0dcbb5f2ed983d59f101af94eb7f20d39e3c1963136299f7e2b361f89d9e8c6ed16efc4ee3892a205ecb9adc24fdcc176ffd4b9839e9b896592eb9d623b1106464e605b821da340200086e61afb91ea2a377e89577e57f00357f504513c00b590000000049454e44ae426082</data> + </image> +</images> +<tqlayoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/chalk/ui/wdgautogradient.ui b/chalk/ui/wdgautogradient.ui new file mode 100644 index 00000000..59875f87 --- /dev/null +++ b/chalk/ui/wdgautogradient.ui @@ -0,0 +1,399 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>KisWdgAutogradient</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>KisWdgAutogradient</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>174</width> + <height>180</height> + </rect> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>0</number> + </property> + <widget class="TQGroupBox" row="0" column="0"> + <property name="name"> + <cstring>groupBox1</cstring> + </property> + <property name="title"> + <string>Custom Gradient</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KisGradientSliderWidget"> + <property name="name"> + <cstring>gradientSlider</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="tqmaximumSize"> + <size> + <width>32767</width> + <height>30</height> + </size> + </property> + <property name="focusPolicy"> + <enum>ClickFocus</enum> + </property> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout11</cstring> + </property> + <property name="font"> + <font> + <family>Arial Unicode MS</family> + <pointsize>6</pointsize> + </font> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout10</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>Segment Color</string> + </property> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout8</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>labelLeftColor</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>Left:</string> + </property> + </widget> + <widget class="KColorButton"> + <property name="name"> + <cstring>leftColorButton</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="tqmaximumSize"> + <size> + <width>30</width> + <height>30</height> + </size> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="focusPolicy"> + <enum>ClickFocus</enum> + </property> + <property name="text"> + <string></string> + </property> + </widget> + </hbox> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout9</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>labelRightColor</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>Right:</string> + </property> + </widget> + <widget class="KColorButton"> + <property name="name"> + <cstring>rightColorButton</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="tqmaximumSize"> + <size> + <width>30</width> + <height>30</height> + </size> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="focusPolicy"> + <enum>ClickFocus</enum> + </property> + <property name="text"> + <string></string> + </property> + </widget> + </hbox> + </widget> + </vbox> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout5</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>Opacity:</string> + </property> + </widget> + <widget class="KIntSpinBox"> + <property name="name"> + <cstring>intNumInputLeftOpacity</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="focusPolicy"> + <enum>ClickFocus</enum> + </property> + <property name="suffix"> + <string>%</string> + </property> + <property name="maxValue"> + <number>100</number> + </property> + </widget> + <widget class="KIntSpinBox"> + <property name="name"> + <cstring>intNumInputRightOpacity</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="focusPolicy"> + <enum>ClickFocus</enum> + </property> + <property name="suffix"> + <string>%</string> + </property> + <property name="maxValue"> + <number>100</number> + </property> + </widget> + </vbox> + </widget> + </hbox> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout11_2</cstring> + </property> + <property name="font"> + <font> + <family>Arial Unicode MS</family> + <pointsize>6</pointsize> + </font> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQComboBox"> + <item> + <property name="text"> + <string>Linear</string> + </property> + </item> + <item> + <property name="text"> + <string>Curved</string> + </property> + </item> + <item> + <property name="text"> + <string>Sine</string> + </property> + </item> + <item> + <property name="text"> + <string>Sphere Inc.</string> + </property> + </item> + <item> + <property name="text"> + <string>Sphere Dec.</string> + </property> + </item> + <property name="name"> + <cstring>comboBoxInterpolationType</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="focusPolicy"> + <enum>ClickFocus</enum> + </property> + </widget> + <widget class="TQComboBox"> + <item> + <property name="text"> + <string>RGB</string> + </property> + </item> + <item> + <property name="text"> + <string>HSV CW</string> + </property> + </item> + <item> + <property name="text"> + <string>HSV CCW</string> + </property> + </item> + <property name="name"> + <cstring>comboBoxColorInterpolationType</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="focusPolicy"> + <enum>ClickFocus</enum> + </property> + </widget> + </hbox> + </widget> + </vbox> + </widget> + </grid> +</widget> +<customwidgets> + <customwidget> + <class>KisGradientSliderWidget</class> + <header location="local">kis_gradient_slider_widget.h</header> + <sizehint> + <width>40</width> + <height>40</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>1</hordata> + <verdata>1</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image0</pixmap> + </customwidget> +</customwidgets> +<images> + <image name="image0"> + <data format="PNG" length="1002">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000003b149444154388dad945f4c5b551cc73fe7dc4b7b4bcba0762d45c43114323599ee6192609c51d883892ce083f1718b3ebb185f8dc91e972cf39d2d2a2f1af664b6f1e0fe3863a0718969700eb0c52142da0242a1bd6d696f7bcff101585203ceb8fd9ece39f99dcff9fe7edf939f88c562ec465f5f9fe609442c161362173c3e3eae7b7a7ac8e7f36432196cdbfe4f907c3e4f2291201e8fe338cec3737357e9e8e828aded1e229d650e1f2d51754b082110124c13a4dc5ea341eb9dc284c0558a853f3ce8cb0677ef500fde7d39d2596679e326597b8e9abb85d7a770ab16ab6983ec5a05b487a70e36f0f4e10afe408d6a558310980108478dba4a1e8233990c5d474b64ed39aa3a8fe5f3317fbf81dbd70bccfeb205947632fd74f6589c1c6ea2f70d03a58ba0c1f2c9bdc1b66de3b8256a6e11cbe7e3ee1d181b590124fe2693aeee08d223c82c3a2c24b7b874bec8f26288774f7bd054504aef0dde6e99c0eb83f9fb266323cb80a27fb0958141836044605a2ee5523393371cc646fee2da37195aa35d0c0c5b4859ac03d7e91712dcaac5adab3650a3ff9d08ef7dd8404bb48869e5d958b5b87dadc4c9a1464e9f0d0326df7ebd86bd2e310cb1bf62d384d59441f2d70a070e1c60e09489929b988681bdd9cc97170bcc4c65595f71f8e0e3301337fc24a7732467831875a47f289652b0be5e4151e6d07316c1b0c0340d8ab92023e76d66a6b2840e36d2fb7a13fee632475e6edc367ea98a90fb98b7dd6310ca0328a44761582e1bab41befabcc0ec940d28bc5e93b68e064cab84e1d9beaeb48934eac1f53b01c1b000fca496aa54b61a99fcde61662a4b4b4b23d1680be9d426173e4df3602a48ea411989a4fd590f52a8fd156b05ed9d350e3defe3cfdf4b4c7ce770ea7d3fb9f520afbe1620daeee5c26735d20b9b9cfb6811a754a439e4e5c5639a4caa1e5caf586bfc0197b78702005cb9b4cae4cd3267ce8638fe964bd72b393e39d74928d242617303a756a37f284447770dcdbffc6384a05a85de1306e9a52057c7527c7131c3c42d3f475eb2303c82d4fc3276d6811db37efeb148723082d9b08f79f97c1e5729109a9a28307cc622d2d6cdf52b2b24efe548dedb00142009862cfa879ee1a71f6cec928353511472fbf4389148b0b0e0c108081412458dfe21c9f11351e67e7358595468246d1d1e5e38a6e9e851bc39d84ab502a669331dafec0d8ec7e3e8cb06e1a881d727d1ae40180a434a8c9db129a54126ad48a7358c2b4c5352c8c374bcccdab2bb37d8719cba79fab8211f9df218e0582c261e95f8bfc04f1a1e8bc5c4dfe0a190172af6a9690000000049454e44ae426082</data> + </image> +</images> +<tqlayoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kcolorbutton.h</includehint> +</includehints> +</UI> diff --git a/chalk/ui/wdgbirdeye.ui b/chalk/ui/wdgbirdeye.ui new file mode 100644 index 00000000..77f03131 --- /dev/null +++ b/chalk/ui/wdgbirdeye.ui @@ -0,0 +1,304 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>WdgBirdEye</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>WdgBirdEye</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>188</width> + <height>126</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>1</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="caption"> + <string>Overview</string> + </property> + <property name="tqlayoutMargin" stdset="0"> + </property> + <property name="tqlayoutSpacing" stdset="0"> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>0</number> + </property> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>1</number> + </property> + <property name="spacing"> + <number>1</number> + </property> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout10</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>lblX</cstring> + </property> + <property name="text"> + <string>X:</string> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>txtX</cstring> + </property> + <property name="tqminimumSize"> + <size> + <width>50</width> + <height>0</height> + </size> + </property> + <property name="tqmaximumSize"> + <size> + <width>50</width> + <height>32767</height> + </size> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>Plain</enum> + </property> + <property name="text"> + <string>00000</string> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>lblY</cstring> + </property> + <property name="text"> + <string>Y:</string> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>txtY</cstring> + </property> + <property name="tqminimumSize"> + <size> + <width>50</width> + <height>0</height> + </size> + </property> + <property name="tqmaximumSize"> + <size> + <width>50</width> + <height>32767</height> + </size> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>Plain</enum> + </property> + <property name="text"> + <string>00000</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer6</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </vbox> + </widget> + <widget class="TQFrame"> + <property name="name"> + <cstring>view</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>2</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="tqminimumSize"> + <size> + <width>75</width> + <height>75</height> + </size> + </property> + <property name="tqmaximumSize"> + <size> + <width>200</width> + <height>75</height> + </size> + </property> + <property name="mouseTracking"> + <bool>true</bool> + </property> + <property name="frameShape"> + <enum>Box</enum> + </property> + <property name="frameShadow"> + <enum>Raised</enum> + </property> + </widget> + </hbox> + </widget> + <widget class="KToolBar"> + <property name="name"> + <cstring>toolbar</cstring> + </property> + <property name="tqmaximumSize"> + <size> + <width>32767</width> + <height>32</height> + </size> + </property> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>1</number> + </property> + <property name="spacing"> + <number>1</number> + </property> + <widget class="KIntSpinBox"> + <property name="name"> + <cstring>zoom</cstring> + </property> + <property name="suffix"> + <string></string> + </property> + <property name="maxValue"> + <number>1600</number> + </property> + <property name="minValue"> + <number>10</number> + </property> + <property name="lineStep"> + <number>10</number> + </property> + </widget> + <widget class="TQSlider"> + <property name="name"> + <cstring>slZoom</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maxValue"> + <number>19</number> + </property> + <property name="pageStep"> + <number>1</number> + </property> + <property name="value"> + <number>10</number> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="TQToolButton"> + <property name="name"> + <cstring>bn100</cstring> + </property> + <property name="text"> + <string>1:1</string> + </property> + <property name="toolTip" stdset="0"> + <string>Zoom to 100%</string> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<customwidgets> + <customwidget> + <class>KToolBar</class> + <header location="local">ktoolbar.h</header> + <sizehint> + <width>20</width> + <height>100</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image0</pixmap> + </customwidget> +</customwidgets> +<images> + <image name="image0"> + <data format="PNG" length="730">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000002a149444154388db595df4b536118c73f3bdbecf8036c4e41f2c6695022045e486e90b721e4ba126f1a0966627f4108512004a197fd0586588220980a9a068be63abaa884cc1f6d30a7e29cfb216dceb39d9d2e2cf3c74997e417de97972fbc9fe77d1e789e57e772b9384d369b4d3deab95c2edd497784b3404ff20f460650fff732fc0ee0f5bc241298252dc710f4174e4be4908cb9661439cefa7c0fb71eee79fbe0486096b5af3d644e4e50537a3de880b4f2c7db07a7e51819156e77fe3b1860b4bb1095d871f0c1f4239108068381f84e9cc58545c6c7c78946a3d45dafa3b4b414511411f34456d756e9eded65706090924a076bdf9e1f071fd4c0c000c15010f7b49bc93793b4de6ba5abab0bd3451300bbbbbb783e7a08ac04d858dfd0cc4013dcdedebe7f368a462449a2ff553fcd4dcdf87c3eba7bba71bbdcf8fd7e8a8a8ab20703d4d6d6d2f1a00383d180b9c84c85a58282fc027c3e1ff537ea71dc71303a36caf6f6367d2ffab203773eeaa4e1660336ab8db49226c798839c9211f402b22c53535383cd6ac35261c1eff76b82353b4fafd7a3a80a899d048220904aa588842324779278bd5e9cef9cc41371ca2e9511de0a675f8ae1a161cc2633e5e5e5980a4d0882c06678133157243f2f9f85a50526a62698fb32c78c674613acf962dfb28fd05688443c41329944de95997e3fcdc8e8088b4b8bb85d6e42c110f6463b5557aab207c77ec458febe8c3fe067657585542a85d566c5bbecc5fdc18de5b285603088925168b9db927d294451c4e9745275b50a7ba39dc44e8292e212daeeb7517dad9aa9b7534833129224d1d4d4a409de9f6e9fc61eabaf9f9d7d9a7d1e7ba20e3dd5986e8a1c47c75ecf97543ab45ff117e5e416138f7af790474bb13edf435a0195d8a19ecf46eaaf2d9339609ed7a03ff56b3aabce0dfc13238259bff00a6d890000000049454e44ae426082</data> + </image> +</images> +<includes> + <include location="local" impldecl="in declaration">kiconloader.h</include> +</includes> +<Q_SLOTS> + <slot>zoomChanged(int)</slot> + <slot>zoomMinus()</slot> + <slot>zoomPlus()</slot> +</Q_SLOTS> +<pixmapfunction>BarIcon</pixmapfunction> +<tqlayoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>ktoolbar.h</includehint> + <includehint>knuminput.h</includehint> +</includehints> +</UI> diff --git a/chalk/ui/wdgcolorsettings.ui b/chalk/ui/wdgcolorsettings.ui new file mode 100644 index 00000000..3d2def86 --- /dev/null +++ b/chalk/ui/wdgcolorsettings.ui @@ -0,0 +1,357 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>WdgColorSettings</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>WdgColorSettings</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>586</width> + <height>457</height> + </rect> + </property> + <property name="caption"> + <string>Color Settings</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout8</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel1_2</cstring> + </property> + <property name="text"> + <string>Default color model for new images:</string> + </property> + </widget> + <widget class="KisCmbIDList"> + <property name="name"> + <cstring>cmbWorkingColorSpace</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="tqminimumSize"> + <size> + <width>0</width> + <height>20</height> + </size> + </property> + </widget> + </hbox> + </widget> + <widget class="TQButtonGroup"> + <property name="name"> + <cstring>grpDisplay</cstring> + </property> + <property name="title"> + <string>Display</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>&Monitor profile:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cmbPrintProfile</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>The icm profile for your calibrated monitor.</string> + </property> + </widget> + <widget class="TQLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel1_4</cstring> + </property> + <property name="text"> + <string>&Rendering intent:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cmbMonitorIntent</cstring> + </property> + <property name="whatsThis" stdset="0"> + <string>In converting the image data to be shown on screen you can select different ways in which to handle colors that can not be displayed on a monitor (out of gamut). +The different rendering intent methods will affect only what is shown on screen, and exporting or printing the image will not be affected. +<li>Perceptual, shows full gamut. Recommended for photographic images.</li> +<li>Relative Colorimetric, also called Proof or Preserve Identical Color and White Point. Reproduces in-gamut colors and clips out-of-gamut colors to the nearest reproducible color.</li> +<li>Absolute Colorimetric, much like Relative Colorimetric but it sacrificing saturation and possibly lightness for out-of-gamut colors. Rarely of use for photographic images.</li><li>Saturation, Preserves saturation. Convert from the saturated primary colors in the image to saturated primary colors on screen.</li></string> + </property> + </widget> + <widget class="KComboBox" row="1" column="1"> + <item> + <property name="text"> + <string>Perceptual</string> + </property> + </item> + <item> + <property name="text"> + <string>Relative Colorimetric</string> + </property> + </item> + <item> + <property name="text"> + <string>Saturation</string> + </property> + </item> + <item> + <property name="text"> + <string>Absolute Colorimetric</string> + </property> + </item> + <property name="name"> + <cstring>cmbMonitorIntent</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="whatsThis" stdset="0"> + <string>In converting the image data to be shown on screen you can select different ways in which to handle colors that can not be displayed on a monitor (out of gamut). +The different rendering intent methods will affect only what is shown on screen, and exporting or printing the image will not be affected. +<li>Perceptual, shows full gamut. Recommended for photographic images.</li> +<li>Relative Colorimetric, also called Proof or Preserve Identical Color and White Point. Reproduces in-gamut colors and clips out-of-gamut colors to the nearest reproducible color.</li> +<li>Absolute Colorimetric, much like Relative Colorimetric but it sacrificing saturation and possibly lightness for out-of-gamut colors. Rarely of use for photographic images.</li><li>Saturation, Preserves saturation. Convert from the saturated primary colors in the image to saturated primary colors on screen.</li></string> + </property> + </widget> + <widget class="SqueezedComboBox" row="0" column="1"> + <property name="name"> + <cstring>cmbMonitorProfile</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </grid> + </widget> + <widget class="TQGroupBox"> + <property name="name"> + <cstring>groupBox2</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="title"> + <string>Printing</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KisCmbIDList" row="0" column="1"> + <property name="name"> + <cstring>cmbPrintingColorSpace</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + <widget class="KComboBox" row="1" column="1"> + <property name="name"> + <cstring>cmbPrintProfile</cstring> + </property> + </widget> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>lbldefaultprinterspace</cstring> + </property> + <property name="text"> + <string>Color model:</string> + </property> + </widget> + <widget class="TQLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel4</cstring> + </property> + <property name="text"> + <string>Profile:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cmbPrintProfile</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>The icm profile for your calibrated printer</string> + </property> + </widget> + </grid> + </widget> + <widget class="TQButtonGroup"> + <property name="name"> + <cstring>grpPasteBehaviour</cstring> + </property> + <property name="title"> + <string>Profile on Paste</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel1_2_2</cstring> + </property> + <property name="text"> + <string><p>Select what color profile to add when pasting from external applications that do not use a color profile.</p></string> + </property> + <property name="tqalignment"> + <set>WordBreak|AlignVCenter</set> + </property> + </widget> + <widget class="TQRadioButton"> + <property name="name"> + <cstring>radioPasteWeb</cstring> + </property> + <property name="text"> + <string>Use sRGB</string> + </property> + <property name="toolTip" stdset="0"> + <string>sRGB are like images from the web are supposed to be seen.</string> + </property> + </widget> + <widget class="TQRadioButton"> + <property name="name"> + <cstring>radioPasteMonitor</cstring> + </property> + <property name="text"> + <string>Use monitor profile</string> + </property> + <property name="toolTip" stdset="0"> + <string>This is like you see it in the other application</string> + </property> + </widget> + <widget class="TQRadioButton"> + <property name="name"> + <cstring>radioPasteAsk</cstring> + </property> + <property name="text"> + <string>Ask</string> + </property> + </widget> + </vbox> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout6</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQCheckBox"> + <property name="name"> + <cstring>chkBlackpoint</cstring> + </property> + <property name="text"> + <string>Use Blackpoint compensation</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </vbox> + </widget> + <spacer> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>20</width> + <height>16</height> + </size> + </property> + </spacer> + </vbox> +</widget> +<customwidgets> + <customwidget> + <class>KisCmbIDList</class> + <header location="local">kis_cmb_idlist.h</header> + <sizehint> + <width>1</width> + <height>24</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image0</pixmap> + </customwidget> + <customwidget> + <class>SqueezedComboBox</class> + <header location="local">squeezedcombobox.h</header> + <sizehint> + <width>-1</width> + <height>0</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>3</hordata> + <verdata>0</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image1</pixmap> + </customwidget> +</customwidgets> +<images> + <image name="image0"> + <data format="PNG" length="870">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000032d49444154388db59531681c4714863f892dde8004b320c32e3870020b74458a6b0f5458e581c016a809a8496b42208454098604d2c4904a6954a410511ae752085b858c1208dc35221244b00119f60ac12ee860062c980719708a95a248f129459cd7cceeccf0edb76fff61a706830197d5ed765ff3166a30184c4d5d829fed3c7bdd5e6ce3bda71a5738ef301802e1d6d179477152303c1842bc822797a64fbf7b4a9a43be00ada817cb0e12011c2611205ccd73755f9c087c6b19bef0d7c100f5b8267d07caf10fe8ab9210156320fc01be16aa5a11043307f30b20a21041019985f48ef2f7fa0becc68e80475fd584e831b396f210f67795c3831a4940a3228925bb27f4d652ba4b01a199b73342f3981be0ca57745042ac30c632d853b6373d44b056c8ef0922508d94d14be59b2f4aeaf58cd5751069e06f3436890114332b9487d0bf80f61e64dc5f813c3790045453f67703fd4d4f7f6b4496b5597e689044af194f5f5e841800210478bee3d1a8f41e64acbe0f69ae6852e1cf0ccf7f74f4d652defbc042226c6f55e8f89f91bb6e9c387c9d521c9558db988a3416fe3c67e32b4779ec7167f0e8939ce19ea7fc5d298a80c875f03563930855ed2081bc05e91d5014ef53363eaf288e3d6285ee520a338e76c7a251a94e41e30470d3631004a262672e3eca59cec6978ef2b889979d11f2bb904af3be92081a416e28dfe831983920b1142345d5b0ff2234a6334276d7321ad53c795c511ca654a5a251996f19b83d158ef602b45a423d52f67703abeb29ee4ce9de4fc93378f218462f6b3efdb042cf3d59666977a0aa6fe9310888d25b13342afd4dcffeaee3d147399da540ab13f8f8b39c2cb3f8710d11ba2b96f9c57fcd7180287497a03ecde86f8dd8fe1a867b9ef6bb1612a84a871f6bd35b94e217a53832589970f2dcd85d9c7d4580d57521cbdaf4bfaf288e95e268d4ec8e60e72ccb0f2dbffea454e71e8d29f57882717152509482a48d8924b0bc12e82ee51445a03a6da079cbd0eec0fc22142b06620e89a3fc8d3783870743d814d2bc8994aa6ff286472e764902e5a96f72bbd3b4c37b280e95aa9e604c84e1cf978b37c74935797d7ae2ca7fac6968fe51ff0bf86dc30783c1d49f0baa9bb819e612310000000049454e44ae426082</data> + </image> + <image name="image1"> + <data format="PNG" length="1003">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000003b249444154388db5944d4c5c5518869f73ce9db9cc40f929cc30300e18129a50685268a28291982e1a2175212eaab1c49d3f8971e7aec6aedb54a32b435dd8685cb8c0c4b8b0feb421b7bd8186a069d23209144b18cb0c02f3732ff3c3ccbdd705a571941213f1dd9d93739ef37e6fbeef08d334d9d5d0d090c701c8344d2176c1a6697a5d5d5dd8b64d2a95c2b2ac7f05b12c8b783c8e6118d8b6fd685fdb753a39394928e2a7c55724d693a7e214104220242805520a84d8b9e4790f0b1302c7751958f1e30534be9fa41a0c60db362dbe227f64af91b6e7719c2dfc0117a71c603da591de2882a7d3d4ec27122b10acad50aeb88044d542b84de3af7ab44aa55274f4e449dbf354bc347aa096fbf37e7efa2ecbad1b36907d78b289de8120232f37726250c3f52cf0a026a0f6065b9645d929e038167aa096d91b307171059034b5f8e9e9eb44fa052b4b25eeccd9dc99cb71f6ad082fbea2e351c075bdbdc13b9109fc01b83fef63e2e232e03076b68393231a0dcd024daf502c1e66e67a89cb971ef0e5a74bb4b61e6378248094b92ab0ac024b70ca017ef8360394187b2dc6d8b89ffa500e4d4f93d9083275d5e6f9913ade3dd70ee87c7d25c95646a25415aadab152b09ed4f8c5cc130a853839eac3951b684a61e70ef3f9c739668c24eba912afbfddc6d4d506e6a6d7b8b7d082aa8eb8dab19482cdcd220e36dd3dc19df23545de0a71f952861923493456cfd3cf36123c54a0b7bf0e8064621b21f7712c040857071ca4eea0f40a99f510573ec971cb48030e811a1faded3e94be85f2fb00703d1ff26f96ab9f011a5b04d0c4f26fdb948a754c1b25668c2491483d5d5d611617d6b8f0fe32cb779b492ce65168b4c774a4701eefd8f3a02d56e6e8f13aeefe9a63fa5a89d1970e91d908f3d46003e1480d173e28b37827c9b977348ab92ce16890237d1ec907ee3e8e3d8f60d0e1f4583d009f7d9860662acff89bad1c1faad0717493f7ce7713ed8cb0995c255f2a317a26427b67198f6a70f51c0a41b902279ed1187f23cc17130b7c74de65eac77a7a8f05517e41e2deefa4930576db60fa7a8ee1535134df3e93e7b82e0817476439fd6a9070a49f6fbe4a3077739db99b15c001146dd13a46cf1cc1f83943c62e51de76b0738fc9381e8f3390f0236b252e124999e11724fd833196164bacadb87848224fe874f779b43fe9f2dca928956d505a96dbb3f9bdc18661e00534c26d1a7a40e13912a11c9454280da41048a9915c75585df500074d53d816dc9edd229528ef0db66dbbea3ffdaffa471f1f28d8344df1bf800f1a6e9aa6f813c39885bc050f269c0000000049454e44ae426082</data> + </image> +</images> +<tqlayoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kis_cmb_idlist.h</includehint> + <includehint>kcombobox.h</includehint> + <includehint>squeezedcombobox.h</includehint> + <includehint>kis_cmb_idlist.h</includehint> + <includehint>kcombobox.h</includehint> +</includehints> +</UI> diff --git a/chalk/ui/wdgcustombrush.ui b/chalk/ui/wdgcustombrush.ui new file mode 100644 index 00000000..78c77be3 --- /dev/null +++ b/chalk/ui/wdgcustombrush.ui @@ -0,0 +1,199 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>KisWdgCustomBrush</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>KisWdgCustomBrush</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>267</width> + <height>265</height> + </rect> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout4</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="text"> + <string>Style:</string> + </property> + </widget> + <widget class="TQComboBox" row="2" column="1"> + <item> + <property name="text"> + <string>Constant</string> + </property> + </item> + <item> + <property name="text"> + <string>Random</string> + </property> + </item> + <item> + <property name="text"> + <string>Incremental</string> + </property> + </item> + <item> + <property name="text"> + <string>Pressure</string> + </property> + </item> + <item> + <property name="text"> + <string>Angular</string> + </property> + </item> + <property name="name"> + <cstring>comboBox2</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="currentItem"> + <number>2</number> + </property> + </widget> + <widget class="TQLabel" row="2" column="0"> + <property name="name"> + <cstring>textLabel3</cstring> + </property> + <property name="text"> + <string>Selection mode:</string> + </property> + </widget> + <widget class="TQComboBox" row="0" column="1"> + <item> + <property name="text"> + <string>Regular</string> + </property> + </item> + <item> + <property name="text"> + <string>Animated</string> + </property> + </item> + <property name="name"> + <cstring>style</cstring> + </property> + </widget> + </grid> + </widget> + <widget class="TQCheckBox"> + <property name="name"> + <cstring>colorAsMask</cstring> + </property> + <property name="text"> + <string>Use color as tqmask</string> + </property> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout6</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="TQLabel"> + <property name="name"> + <cstring>preview</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="tqminimumSize"> + <size> + <width>50</width> + <height>50</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout7</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQPushButton"> + <property name="name"> + <cstring>brushButton</cstring> + </property> + <property name="text"> + <string>Use as Brush</string> + </property> + </widget> + <widget class="TQPushButton"> + <property name="name"> + <cstring>addButton</cstring> + </property> + <property name="text"> + <string>Add to Predefined Brushes</string> + </property> + </widget> + </vbox> + </widget> + </vbox> +</widget> +<tqlayoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/chalk/ui/wdgcustompalette.ui b/chalk/ui/wdgcustompalette.ui new file mode 100644 index 00000000..c5cbe9dc --- /dev/null +++ b/chalk/ui/wdgcustompalette.ui @@ -0,0 +1,88 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>KisWdgCustomPalette</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>KisWdgCustomPalette</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>282</width> + <height>384</height> + </rect> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLineEdit"> + <property name="name"> + <cstring>palettename</cstring> + </property> + <property name="text"> + <string>Unnamed</string> + </property> + </widget> + <widget class="KisPaletteView"> + <property name="name"> + <cstring>view</cstring> + </property> + </widget> + <widget class="TQPushButton"> + <property name="name"> + <cstring>addColor</cstring> + </property> + <property name="text"> + <string>Add New Color...</string> + </property> + </widget> + <widget class="TQPushButton"> + <property name="name"> + <cstring>removeColor</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="text"> + <string>Remove Selected Color</string> + </property> + </widget> + <widget class="TQPushButton"> + <property name="name"> + <cstring>addPalette</cstring> + </property> + <property name="text"> + <string>Add to Predefined Palettes</string> + </property> + </widget> + </vbox> +</widget> +<customwidgets> + <customwidget> + <class>KisPaletteView</class> + <header location="local">kis_palette_view.h</header> + <sizehint> + <width>-1</width> + <height>-1</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image0</pixmap> + </customwidget> +</customwidgets> +<images> + <image name="image0"> + <data format="PNG" length="1003">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000003b249444154388db5944d4c5c5518869f73ce9db9cc40f929cc30300e18129a50685268a28291982e1a2175212eaab1c49d3f8971e7aec6aedb54a32b435dd8685cb8c0c4b8b0feb421b7bd8186a069d23209144b18cb0c02f3732ff3c3ccbdd705a571941213f1dd9d93739ef37e6fbeef08d334d9d5d0d090c701c8344d2176c1a6697a5d5d5dd8b64d2a95c2b2ac7f05b12c8b783c8e6118d8b6fd685fdb753a39394928e2a7c55724d693a7e214104220242805520a84d8b9e4790f0b1302c7751958f1e30534be9fa41a0c60db362dbe227f64af91b6e7719c2dfc0117a71c603da591de2882a7d3d4ec27122b10acad50aeb88044d542b84de3af7ab44aa55274f4e449dbf354bc347aa096fbf37e7efa2ecbad1b36907d78b289de8120232f37726250c3f52cf0a026a0f6065b9645d929e038167aa096d91b307171059034b5f8e9e9eb44fa052b4b25eeccd9dc99cb71f6ad082fbea2e351c075bdbdc13b9109fc01b83fef63e2e232e03076b68393231a0dcd024daf502c1e66e67a89cb971ef0e5a74bb4b61e6378248094b92ab0ac024b70ca017ef8360394187b2dc6d8b89ffa500e4d4f93d9083275d5e6f9913ade3dd70ee87c7d25c95646a25415aadab152b09ed4f8c5cc130a853839eac3951b684a61e70ef3f9c739668c24eba912afbfddc6d4d506e6a6d7b8b7d082aa8eb8dab19482cdcd220e36dd3dc19df23545de0a71f952861923493456cfd3cf36123c54a0b7bf0e8064621b21f7712c040857071ca4eea0f40a99f510573ec971cb48030e811a1faded3e94be85f2fb00703d1ff26f96ab9f011a5b04d0c4f26fdb948a754c1b25668c2491483d5d5d611617d6b8f0fe32cb779b492ce65168b4c774a4701eefd8f3a02d56e6e8f13aeefe9a63fa5a89d1970e91d908f3d46003e1480d173e28b37827c9b977348ab92ce16890237d1ec907ee3e8e3d8f60d0e1f4583d009f7d9860662acff89bad1c1faad0717493f7ce7713ed8cb0995c255f2a317a26427b67198f6a70f51c0a41b902279ed1187f23cc17130b7c74de65eac77a7a8f05517e41e2deefa4930576db60fa7a8ee1535134df3e93e7b82e0817476439fd6a9070a49f6fbe4a3077739db99b15c001146dd13a46cf1cc1f83943c62e51de76b0738fc9381e8f3390f0236b252e124999e11724fd833196164bacadb87848224fe874f779b43fe9f2dca928956d505a96dbb3f9bdc18661e00534c26d1a7a40e13912a11c9454280da41048a9915c75585df500074d53d816dc9edd229528ef0db66dbbea3ffdaffa471f1f28d8344df1bf800f1a6e9aa6f813c39885bc050f269c0000000049454e44ae426082</data> + </image> +</images> +<tqlayoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kis_palette_view.h</includehint> +</includehints> +</UI> diff --git a/chalk/ui/wdgcustompattern.ui b/chalk/ui/wdgcustompattern.ui new file mode 100644 index 00000000..d195f670 --- /dev/null +++ b/chalk/ui/wdgcustompattern.ui @@ -0,0 +1,156 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>KisWdgCustomPattern</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>KisWdgCustomPattern</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>255</width> + <height>232</height> + </rect> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Source:</string> + </property> + </widget> + <widget class="TQComboBox"> + <item> + <property name="text"> + <string>Entire Image</string> + </property> + </item> + <property name="name"> + <cstring>comboBox1</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + </hbox> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout6</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="TQLabel"> + <property name="name"> + <cstring>preview</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="tqminimumSize"> + <size> + <width>50</width> + <height>50</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout7</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQPushButton"> + <property name="name"> + <cstring>patternButton</cstring> + </property> + <property name="text"> + <string>Use as Pattern</string> + </property> + </widget> + <widget class="TQPushButton"> + <property name="name"> + <cstring>exportButton</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Export</string> + </property> + </widget> + <widget class="TQPushButton"> + <property name="name"> + <cstring>addButton</cstring> + </property> + <property name="text"> + <string>Add to Predefined Patterns</string> + </property> + </widget> + </vbox> + </widget> + </vbox> +</widget> +<tqlayoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/chalk/ui/wdgdisplaysettings.ui b/chalk/ui/wdgdisplaysettings.ui new file mode 100644 index 00000000..990f316b --- /dev/null +++ b/chalk/ui/wdgdisplaysettings.ui @@ -0,0 +1,90 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>WdgDisplaySettings</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>WdgDisplaySettings</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>374</width> + <height>154</height> + </rect> + </property> + <property name="caption"> + <string>Display</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer3</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>20</width> + <height>50</height> + </size> + </property> + </spacer> + <widget class="TQButtonGroup" row="0" column="0"> + <property name="name"> + <cstring>buttonGroup1</cstring> + </property> + <property name="title"> + <string>OpenGL</string> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout4</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQCheckBox"> + <property name="name"> + <cstring>cbUseOpenGL</cstring> + </property> + <property name="text"> + <string>Enable OpenGL</string> + </property> + </widget> + </vbox> + </widget> + <spacer> + <property name="name"> + <cstring>spacer4</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>121</width> + <height>31</height> + </size> + </property> + </spacer> + </hbox> + </widget> + </grid> +</widget> +<tqlayoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/chalk/ui/wdggeneralsettings.ui b/chalk/ui/wdggeneralsettings.ui new file mode 100644 index 00000000..051cf795 --- /dev/null +++ b/chalk/ui/wdggeneralsettings.ui @@ -0,0 +1,183 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>WdgGeneralSettings</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>WdgGeneralSettings</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>335</width> + <height>209</height> + </rect> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>tqlayout3</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>&Cursor tqshape:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>m_cmbtqCursorShape</cstring> + </property> + </widget> + <widget class="TQComboBox"> + <item> + <property name="text"> + <string>Tool Icon</string> + </property> + </item> + <item> + <property name="text"> + <string>Crosshair</string> + </property> + </item> + <item> + <property name="text"> + <string>Arrow</string> + </property> + </item> + <item> + <property name="text"> + <string>Brush Outline</string> + </property> + </item> + <property name="name"> + <cstring>m_cmbtqCursorShape</cstring> + </property> + </widget> + </hbox> + </widget> + <widget class="TQButtonGroup"> + <property name="name"> + <cstring>grpDockability</cstring> + </property> + <property name="title"> + <string>Palette Behavior</string> + </property> + <property name="exclusive"> + <bool>true</bool> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQRadioButton"> + <property name="name"> + <cstring>radioAllowDocking</cstring> + </property> + <property name="text"> + <string>Allow &docking</string> + </property> + </widget> + <widget class="TQRadioButton"> + <property name="name"> + <cstring>radioDisallowDocking</cstring> + </property> + <property name="text"> + <string>Allow only &floating</string> + </property> + </widget> + <widget class="TQRadioButton"> + <property name="name"> + <cstring>radioSmartDocking</cstring> + </property> + <property name="text"> + <string>Allow docking only on &large screens</string> + </property> + </widget> + </vbox> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel1_2</cstring> + </property> + <property name="text"> + <string>&Palette font size:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>numDockerFontSize</cstring> + </property> + </widget> + <widget class="KIntNumInput"> + <property name="name"> + <cstring>numDockerFontSize</cstring> + </property> + </widget> + </hbox> + </widget> + </vbox> + </widget> + <spacer row="0" column="1"> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>41</width> + <height>20</height> + </size> + </property> + </spacer> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>20</width> + <height>41</height> + </size> + </property> + </spacer> + </grid> +</widget> +<customwidgets> +</customwidgets> +<tqlayoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>knuminput.h</includehint> +</includehints> +</UI> diff --git a/chalk/ui/wdggridsettings.ui b/chalk/ui/wdggridsettings.ui new file mode 100644 index 00000000..a89574d1 --- /dev/null +++ b/chalk/ui/wdggridsettings.ui @@ -0,0 +1,468 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>WdgGridSettingsBase</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>WdgGridSettingsBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>422</width> + <height>233</height> + </rect> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <spacer row="2" column="0"> + <property name="name"> + <cstring>spacer14</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>20</width> + <height>31</height> + </size> + </property> + </spacer> + <widget class="TQGroupBox" row="0" column="1"> + <property name="name"> + <cstring>groupBox9</cstring> + </property> + <property name="title"> + <string>Colors</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="0" column="2" rowspan="2" colspan="1"> + <property name="name"> + <cstring>spacer12_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>16</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="KColorButton" row="0" column="1"> + <property name="name"> + <cstring>colorMain</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="color"> + <color> + <red>99</red> + <green>99</green> + <blue>99</blue> + </color> + </property> + </widget> + <widget class="TQLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel3</cstring> + </property> + <property name="text"> + <string>Subdivision:</string> + </property> + </widget> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel2_4</cstring> + </property> + <property name="text"> + <string>Main:</string> + </property> + </widget> + <widget class="KColorButton" row="1" column="1"> + <property name="name"> + <cstring>colorSubdivision</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="color"> + <color> + <red>200</red> + <green>200</green> + <blue>200</blue> + </color> + </property> + </widget> + </grid> + </widget> + <widget class="TQGroupBox" row="0" column="0"> + <property name="name"> + <cstring>groupBox5</cstring> + </property> + <property name="title"> + <string>Styles</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel4</cstring> + </property> + <property name="text"> + <string>Main:</string> + </property> + </widget> + <widget class="KComboBox" row="0" column="1"> + <item> + <property name="text"> + <string>Lines</string> + </property> + </item> + <item> + <property name="text"> + <string>Dashed Lines</string> + </property> + </item> + <item> + <property name="text"> + <string>Dots</string> + </property> + </item> + <property name="name"> + <cstring>selectMainStyle</cstring> + </property> + <property name="currentItem"> + <number>0</number> + </property> + </widget> + <widget class="KComboBox" row="1" column="1"> + <item> + <property name="text"> + <string>Lines</string> + </property> + </item> + <item> + <property name="text"> + <string>Dashed Lines</string> + </property> + </item> + <item> + <property name="text"> + <string>Dots</string> + </property> + </item> + <property name="name"> + <cstring>selectSubdivisionStyle</cstring> + </property> + </widget> + <widget class="TQLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel5</cstring> + </property> + <property name="text"> + <string>Subdivision:</string> + </property> + </widget> + <spacer row="0" column="2"> + <property name="name"> + <cstring>spacer15</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>34</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="TQGroupBox" row="1" column="0"> + <property name="name"> + <cstring>groupBox3</cstring> + </property> + <property name="title"> + <string>Spacing</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>tqlayout8</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout6</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>1</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>image0</pixmap> + </property> + </widget> + <widget class="TQLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel2_2</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>image1</pixmap> + </property> + </widget> + <widget class="KIntNumInput" row="1" column="1"> + <property name="name"> + <cstring>intVSpacing</cstring> + </property> + <property name="value"> + <number>10</number> + </property> + <property name="minValue"> + <number>0</number> + </property> + </widget> + <widget class="KIntNumInput" row="0" column="1"> + <property name="name"> + <cstring>intHSpacing</cstring> + </property> + <property name="value"> + <number>10</number> + </property> + <property name="minValue"> + <number>0</number> + </property> + </widget> + </grid> + </widget> + <widget class="TQToolButton"> + <property name="name"> + <cstring>bnLinkSpacing</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="tqminimumSize"> + <size> + <width>16</width> + <height>0</height> + </size> + </property> + <property name="tqmaximumSize"> + <size> + <width>16</width> + <height>32767</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + <property name="toggleButton"> + <bool>true</bool> + </property> + <property name="on"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + <widget class="TQLayoutWidget" row="1" column="0"> + <property name="name"> + <cstring>tqlayout9</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Subdivision:</string> + </property> + </widget> + <widget class="KIntNumInput"> + <property name="name"> + <cstring>intSubdivision</cstring> + </property> + <property name="value"> + <number>2</number> + </property> + <property name="minValue"> + <number>1</number> + </property> + </widget> + </hbox> + </widget> + <spacer row="0" column="1"> + <property name="name"> + <cstring>spacer12</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>41</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="TQGroupBox" row="1" column="1"> + <property name="name"> + <cstring>groupBox3_2</cstring> + </property> + <property name="title"> + <string>Offset</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel2_3</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>1</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>X:</string> + </property> + </widget> + <widget class="TQLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel2_2_2</cstring> + </property> + <property name="text"> + <string>Y:</string> + </property> + </widget> + <widget class="KIntNumInput" row="1" column="1"> + <property name="name"> + <cstring>intOffsetY</cstring> + </property> + <property name="minValue"> + <number>0</number> + </property> + </widget> + <widget class="KIntNumInput" row="0" column="1"> + <property name="name"> + <cstring>intOffsetX</cstring> + </property> + <property name="minValue"> + <number>0</number> + </property> + </widget> + <spacer row="0" column="2"> + <property name="name"> + <cstring>spacer11</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + </widget> + </grid> +</widget> +<customwidgets> +</customwidgets> +<images> + <image name="image0"> + <data format="PNG" length="236">89504e470d0a1a0a0000000d49484452000000190000001a0806000000427df7cd000000b3494441544889dd963112c420084581d97acdfd4f29b9005b3913135050d722bf54f0018223e6ccf06f7db4c594be4d27e63304a190f525885e20154433f646ea050d6512d516887af10075c922f5d7e4ca24da4d439059f803721c4946a1962f798c6641d4da5c05421101445c06b82a6746804d73822202cc67956289a0c89a937b77596790b638abfb59d4da5c017840664196aff97679deab62d39bfcf73cf5ef8160ef4bb4e2e7627657e4909eb694eb071e3b4da9ba4f1ddb0000000049454e44ae426082</data> + </image> + <image name="image1"> + <data format="PNG" length="242">89504e470d0a1a0a0000000d49484452000000190000001a0806000000427df7cd000000b9494441544889dd95410ec4200845b1e9ba78ff538a176056260c5181569bccfca590ff2a204da510ecd601008078ed8778953372cec8db20d23c0a72417aa611900999997941a795500a256d2acf7a434354bf212d4927ebc488a417518d4dd75d0dcbb5f2ed983d59f101af94eb7f20d39e3c1963136299f7e2b361f89d9e8c6ed16efc4ee3892a205ecb9adc24fdcc176ffd4b9839e9b896592eb9d623b1106464e605b821da340200086e61afb91ea2a377e89577e57f00357f504513c00b590000000049454e44ae426082</data> + </image> +</images> +<tqlayoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kcolorbutton.h</includehint> + <includehint>kcolorbutton.h</includehint> + <includehint>kcombobox.h</includehint> + <includehint>kcombobox.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> +</includehints> +</UI> diff --git a/chalk/ui/wdglayerbox.ui b/chalk/ui/wdglayerbox.ui new file mode 100644 index 00000000..9bfe5760 --- /dev/null +++ b/chalk/ui/wdglayerbox.ui @@ -0,0 +1,299 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>WdgLayerBox</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>WdgLayerBox</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>352</width> + <height>542</height> + </rect> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>0</number> + </property> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KisCmbComposite"> + <property name="name"> + <cstring>cmbComposite</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="tqminimumSize"> + <size> + <width>0</width> + <height>10</height> + </size> + </property> + <property name="toolTip" stdset="0"> + <string>Blending mode</string> + </property> + </widget> + <widget class="KisIntSpinbox"> + <property name="name"> + <cstring>intOpacity</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </hbox> + </widget> + <widget class="KisLayerList"> + <property name="name"> + <cstring>listLayers</cstring> + </property> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout6</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQToolButton"> + <property name="name"> + <cstring>bnAdd</cstring> + </property> + <property name="tqminimumSize"> + <size> + <width>22</width> + <height>22</height> + </size> + </property> + <property name="tqmaximumSize"> + <size> + <width>18</width> + <height>18</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + <property name="iconSet"> + <iconset>image0</iconset> + </property> + <property name="toolTip" stdset="0"> + <string>Create a new layer</string> + </property> + </widget> + <widget class="TQToolButton"> + <property name="name"> + <cstring>bnLower</cstring> + </property> + <property name="tqminimumSize"> + <size> + <width>22</width> + <height>22</height> + </size> + </property> + <property name="tqmaximumSize"> + <size> + <width>18</width> + <height>18</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + <property name="iconSet"> + <iconset>image1</iconset> + </property> + <property name="toolTip" stdset="0"> + <string>Move layer down</string> + </property> + </widget> + <widget class="TQToolButton"> + <property name="name"> + <cstring>bnRaise</cstring> + </property> + <property name="tqminimumSize"> + <size> + <width>22</width> + <height>22</height> + </size> + </property> + <property name="tqmaximumSize"> + <size> + <width>18</width> + <height>18</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + <property name="iconSet"> + <iconset>image2</iconset> + </property> + <property name="toolTip" stdset="0"> + <string>Move layer up</string> + </property> + </widget> + <widget class="TQToolButton"> + <property name="name"> + <cstring>bnProperties</cstring> + </property> + <property name="tqminimumSize"> + <size> + <width>22</width> + <height>22</height> + </size> + </property> + <property name="tqmaximumSize"> + <size> + <width>18</width> + <height>18</height> + </size> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="toolTip" stdset="0"> + <string>View or change the layer properties</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="TQToolButton"> + <property name="name"> + <cstring>bnDelete</cstring> + </property> + <property name="tqminimumSize"> + <size> + <width>22</width> + <height>22</height> + </size> + </property> + <property name="tqmaximumSize"> + <size> + <width>18</width> + <height>18</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + <property name="iconSet"> + <iconset>image3</iconset> + </property> + <property name="toolTip" stdset="0"> + <string>Delete the layer</string> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<customwidgets> + <customwidget> + <class>KisCmbComposite</class> + <header location="local">kis_cmb_composite.h</header> + <sizehint> + <width>-1</width> + <height>-1</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image4</pixmap> + </customwidget> + <customwidget> + <class>KisLayerList</class> + <header location="local">kis_layerlist.h</header> + <sizehint> + <width>-1</width> + <height>-1</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image4</pixmap> + </customwidget> + <customwidget> + <class>KisIntSpinbox</class> + <header location="global">kis_int_spinbox.h</header> + <sizehint> + <width>-1</width> + <height>-1</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image4</pixmap> + </customwidget> +</customwidgets> +<images> + <image name="image0"> + <data format="PNG" length="405">89504e470d0a1a0a0000000d49484452000000100000001008060000001ff3ff610000015c49444154388d8592c1aec22010450f94561bbfcda53f60d77e927fe0ca4d5dfb3126d59586b44271780b539eedab7924041866eebd7341c51801381c0e1160384fc7e97462bfdfab69dc0c9b18239bcd265d586b71ced1340dc6bcd3aaaa8a53103d4b071445419ee7e4799e62ebf59aaaaa4612bf02006459465114a985e3f108c076bb4d2066bef45decbdc71883738edd6ec7e572e17abd723e9fff57a094a2280ab4d6e479ceed76e37ebf638c41a95f1bbe2ad05aa7b5ef7b9c732c160b5eafd7286f164044e8ba8ee7f349d334586b59ad56946549dff7a3a7fe0320228808de7b1e8f072242599600841092b2af005a6bdab6c55a0bc072b924840080730e111979f0c7c410026ddba2b54e7330eef34f7c55e0bd9ffdce5a6b628c6459368e4f13bbae1b154d59638c2382d91606234524f52f222967d603a514defbc43cb83db04ddd1f46f2a0ae6beaba26c638621840945209ecf3fe07b32fb7352555170c0000000049454e44ae426082</data> + </image> + <image name="image1"> + <data format="PNG" length="274">89504e470d0a1a0a0000000d49484452000000160000001208060000005f252e2d000000d949444154388ded94210e84301045ffdfecb5b0582c24681a2c1a8e00b24d3900774063d11c0314d8594543a06cd6ace39b9974326f7e3a4d2922f8875e7fa13ee0a3debec33ccf050048625f2e49008088b87c97d69a27841f4c124551b8fc0c3b0e8ba2e877c722a29aa6b1699a5e404765590692ca6bcef78e876140d77519491b86a1d751599600a08c316d100497faedf292246901a8beef31cf33966571b1aa2a07bdebbf0593441cc72d49358e23d675c5b66da8eb1a22a2b4d6b7d0afe0235c44d4344db0d682a432c6b4e7fbbef43e7fc503bee8030549631e4f2cf51e0000000049454e44ae426082</data> + </image> + <image name="image2"> + <data format="PNG" length="275">89504e470d0a1a0a0000000d49484452000000100000001008060000001ff3ff61000000da49444154388dcd92310e83300c45bfab5e872b709ca0b03022b13130b123251720e21830700060820db18623b84b5dd1a22eedd0fe29b6e2e76f27c4ccf84697afaaff02709543dbb62022c84e9c738a994dd77520a2a8aa2a2b7799196118be77e09c53004c5996e8fb1e008cd65a4931119d4790a474cef31cebba62db36344df3801c8b4f0eeaba56004c966598e719de7b78efb1ef3bacb50060e23856c7a72709ee749324099665395995384d531051340c837d05b0d61ad334bdddb8a8280a8ce3484f802008583a1d252e5ef327c0a7fafd4ffc3de006c2bf7b9f44bff3680000000049454e44ae426082</data> + </image> + <image name="image3"> + <data format="PNG" length="312">89504e470d0a1a0a0000000d49484452000000100000001008060000001ff3ff61000000ff49444154388da592318e84300c459f4773072e0105b7a1e10020eeb0ecd57205e8e9902221100851e2a9321b3261a5d5ba89127f3ddbdf1155e53ff1bc4b6459a621bcef7b0975e244755d7fa96a0b20f2a103c0694504634cdbf7fdf7d34bb64551902409499260adc55acbbaae8808aacab22cecfbce711c18635ae0072022344d43cc13077067740480aaaab42c4bf23c679a26b66d631806c671e4380ee679669a268c316f3f1e612557c581fd02eeddf7e802f0c54e749e671414058433fa77d75db8a10b20acaeaaef0eee220ab8081ebf4ba21ef86d3be37c636f4d0c2336bf0ffa008406f926c63604c1470248d354fd5dc736d3759ddc02fe1a2f646fb86fb4737d520000000049454e44ae426082</data> + </image> + <image name="image4"> + <data format="PNG" length="1002">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000003b149444154388dad945f4c5b551cc73fe7dc4b7b4bcba0762d45c43114323599ee6192609c51d883892ce083f1718b3ebb185f8dc91e972cf39d2d2a2f1af664b6f1e0fe3863a0718969700eb0c52142da0242a1bd6d696f7bcff101585203ceb8fd9ece39f99dcff9fe7edf939f88c562ec465f5f9fe609442c161362173c3e3eae7b7a7ac8e7f36432196cdbfe4f907c3e4f2291201e8fe338cec3737357e9e8e828aded1e229d650e1f2d51754b082110124c13a4dc5ea341eb9dc284c0558a853f3ce8cb0677ef500fde7d39d2596679e326597b8e9abb85d7a770ab16ab6983ec5a05b487a70e36f0f4e10afe408d6a558310980108478dba4a1e8233990c5d474b64ed39aa3a8fe5f3317fbf81dbd70bccfeb205947632fd74f6589c1c6ea2f70d03a58ba0c1f2c9bdc1b66de3b8256a6e11cbe7e3ee1d181b590124fe2693aeee08d223c82c3a2c24b7b874bec8f26288774f7bd054504aef0dde6e99c0eb83f9fb266323cb80a27fb0958141836044605a2ee5523393371cc646fee2da37195aa35d0c0c5b4859ac03d7e91712dcaac5adab3650a3ff9d08ef7dd8404bb48869e5d958b5b87dadc4c9a1464e9f0d0326df7ebd86bd2e310cb1bf62d384d59441f2d70a070e1c60e09489929b988681bdd9cc97170bcc4c65595f71f8e0e3301337fc24a7732467831875a47f289652b0be5e4151e6d07316c1b0c0340d8ab92023e76d66a6b2840e36d2fb7a13fee632475e6edc367ea98a90fb98b7dd6310ca0328a44761582e1bab41befabcc0ec940d28bc5e93b68e064cab84e1d9beaeb48934eac1f53b01c1b000fca496aa54b61a99fcde61662a4b4b4b23d1680be9d426173e4df3602a48ea411989a4fd590f52a8fd156b05ed9d350e3defe3cfdf4b4c7ce770ea7d3fb9f520afbe1620daeee5c26735d20b9b9cfb6811a754a439e4e5c5639a4caa1e5caf586bfc0197b78702005cb9b4cae4cd3267ce8638fe964bd72b393e39d74928d242617303a756a37f284447770dcdbffc6384a05a85de1306e9a52057c7527c7131c3c42d3f475eb2303c82d4fc3276d6811db37efeb148723082d9b08f79f97c1e5729109a9a28307cc622d2d6cdf52b2b24efe548dedb00142009862cfa879ee1a71f6cec928353511472fbf4389148b0b0e0c108081412458dfe21c9f11351e67e7358595468246d1d1e5e38a6e9e851bc39d84ab502a669331dafec0d8ec7e3e8cb06e1a881d727d1ae40180a434a8c9db129a54126ad48a7358c2b4c5352c8c374bcccdab2bb37d8719cba79fab8211f9df218e0582c261e95f8bfc04f1a1e8bc5c4dfe0a190172af6a9690000000049454e44ae426082</data> + </image> +</images> +<tqlayoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/chalk/ui/wdglayerproperties.ui b/chalk/ui/wdglayerproperties.ui new file mode 100644 index 00000000..35eb01ad --- /dev/null +++ b/chalk/ui/wdglayerproperties.ui @@ -0,0 +1,170 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>WdgLayerProperties</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>WdgLayerProperties</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>362</width> + <height>210</height> + </rect> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLineEdit" row="0" column="1"> + <property name="name"> + <cstring>editName</cstring> + </property> + </widget> + <widget class="TQLabel" row="3" column="0"> + <property name="name"> + <cstring>textLabel3</cstring> + </property> + <property name="text"> + <string>&Opacity:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>intOpacity</cstring> + </property> + </widget> + <widget class="SqueezedComboBox" row="2" column="1"> + <property name="name"> + <cstring>cmbProfile</cstring> + </property> + </widget> + <widget class="TQLabel" row="4" column="0"> + <property name="name"> + <cstring>textLabel4</cstring> + </property> + <property name="text"> + <string>Composite mode:</string> + </property> + </widget> + <widget class="TQLabel" row="2" column="0"> + <property name="name"> + <cstring>textLabel1_2</cstring> + </property> + <property name="text"> + <string>Profile:</string> + </property> + </widget> + <widget class="TQLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="text"> + <string>Colorspace:</string> + </property> + </widget> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>&Name:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>editName</cstring> + </property> + </widget> + <widget class="KisCmbIDList" row="1" column="1"> + <property name="name"> + <cstring>cmbColorSpaces</cstring> + </property> + </widget> + <widget class="KisCmbComposite" row="4" column="1"> + <property name="name"> + <cstring>cmbComposite</cstring> + </property> + </widget> + <widget class="KisIntSpinbox" row="3" column="1"> + <property name="name"> + <cstring>intOpacity</cstring> + </property> + </widget> + </grid> +</widget> +<customwidgets> + <customwidget> + <class>KisCmbIDList</class> + <header location="local">kis_cmb_idlist.h</header> + <sizehint> + <width>1</width> + <height>24</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image0</pixmap> + </customwidget> + <customwidget> + <class>KisCmbComposite</class> + <header location="local">kis_cmb_composite.h</header> + <sizehint> + <width>-1</width> + <height>-1</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image1</pixmap> + </customwidget> + <customwidget> + <class>KisIntSpinbox</class> + <header location="global">kis_int_spinbox.h</header> + <sizehint> + <width>-1</width> + <height>-1</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image1</pixmap> + </customwidget> + <customwidget> + <class>SqueezedComboBox</class> + <header location="local">squeezedcombobox.h</header> + <sizehint> + <width>-1</width> + <height>i24</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>3</hordata> + <verdata>0</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image2</pixmap> + </customwidget> +</customwidgets> +<images> + <image name="image0"> + <data format="PNG" length="870">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000032d49444154388db59531681c4714863f892dde8004b320c32e3870020b74458a6b0f5458e581c016a809a8496b42208454098604d2c4904a6954a410511ae752085b858c1208dc35221244b00119f60ac12ee860062c980719708a95a248f129459cd7cceeccf0edb76fff61a706830197d5ed765ff3166a30184c4d5d829fed3c7bdd5e6ce3bda71a5738ef301802e1d6d179477152303c1842bc822797a64fbf7b4a9a43be00ada817cb0e12011c2611205ccd73755f9c087c6b19bef0d7c100f5b8267d07caf10fe8ab9210156320fc01be16aa5a11043307f30b20a21041019985f48ef2f7fa0becc68e80475fd584e831b396f210f67795c3831a4940a3228925bb27f4d652ba4b01a199b73342f3981be0ca57745042ac30c632d853b6373d44b056c8ef0922508d94d14be59b2f4aeaf58cd5751069e06f3436890114332b9487d0bf80f61e64dc5f813c3790045453f67703fd4d4f7f6b4496b5597e689044af194f5f5e841800210478bee3d1a8f41e64acbe0f69ae6852e1cf0ccf7f74f4d652defbc042226c6f55e8f89f91bb6e9c387c9d521c9558db988a3416fe3c67e32b4779ec7167f0e8939ce19ea7fc5d298a80c875f03563930855ed2081bc05e91d5014ef53363eaf288e3d6285ee520a338e76c7a251a94e41e30470d3631004a262672e3eca59cec6978ef2b889979d11f2bb904af3be92081a416e28dfe831983920b1142345d5b0ff2234a6334276d7321ad53c795c511ca654a5a251996f19b83d158ef602b45a423d52f67703abeb29ee4ce9de4fc93378f218462f6b3efdb042cf3d59666977a0aa6fe9310888d25b13342afd4dcffeaee3d147399da540ab13f8f8b39c2cb3f8710d11ba2b96f9c57fcd7180287497a03ecde86f8dd8fe1a867b9ef6bb1612a84a871f6bd35b94e217a53832589970f2dcd85d9c7d4580d57521cbdaf4bfaf288e95e268d4ec8e60e72ccb0f2dbffea454e71e8d29f57882717152509482a48d8924b0bc12e82ee51445a03a6da079cbd0eec0fc22142b06620e89a3fc8d3783870743d814d2bc8994aa6ff286472e764902e5a96f72bbd3b4c37b280e95aa9e604c84e1cf978b37c74935797d7ae2ca7fac6968fe51ff0bf86dc30783c1d49f0baa9bb819e612310000000049454e44ae426082</data> + </image> + <image name="image1"> + <data format="PNG" length="1002">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000003b149444154388dad945f4c5b551cc73fe7dc4b7b4bcba0762d45c43114323599ee6192609c51d883892ce083f1718b3ebb185f8dc91e972cf39d2d2a2f1af664b6f1e0fe3863a0718969700eb0c52142da0242a1bd6d696f7bcff101585203ceb8fd9ece39f99dcff9fe7edf939f88c562ec465f5f9fe609442c161362173c3e3eae7b7a7ac8e7f36432196cdbfe4f907c3e4f2291201e8fe338cec3737357e9e8e828aded1e229d650e1f2d51754b082110124c13a4dc5ea341eb9dc284c0558a853f3ce8cb0677ef500fde7d39d2596679e326597b8e9abb85d7a770ab16ab6983ec5a05b487a70e36f0f4e10afe408d6a558310980108478dba4a1e8233990c5d474b64ed39aa3a8fe5f3317fbf81dbd70bccfeb205947632fd74f6589c1c6ea2f70d03a58ba0c1f2c9bdc1b66de3b8256a6e11cbe7e3ee1d181b590124fe2693aeee08d223c82c3a2c24b7b874bec8f26288774f7bd054504aef0dde6e99c0eb83f9fb266323cb80a27fb0958141836044605a2ee5523393371cc646fee2da37195aa35d0c0c5b4859ac03d7e91712dcaac5adab3650a3ff9d08ef7dd8404bb48869e5d958b5b87dadc4c9a1464e9f0d0326df7ebd86bd2e310cb1bf62d384d59441f2d70a070e1c60e09489929b988681bdd9cc97170bcc4c65595f71f8e0e3301337fc24a7732467831875a47f289652b0be5e4151e6d07316c1b0c0340d8ab92023e76d66a6b2840e36d2fb7a13fee632475e6edc367ea98a90fb98b7dd6310ca0328a44761582e1bab41befabcc0ec940d28bc5e93b68e064cab84e1d9beaeb48934eac1f53b01c1b000fca496aa54b61a99fcde61662a4b4b4b23d1680be9d426173e4df3602a48ea411989a4fd590f52a8fd156b05ed9d350e3defe3cfdf4b4c7ce770ea7d3fb9f520afbe1620daeee5c26735d20b9b9cfb6811a754a439e4e5c5639a4caa1e5caf586bfc0197b78702005cb9b4cae4cd3267ce8638fe964bd72b393e39d74928d242617303a756a37f284447770dcdbffc6384a05a85de1306e9a52057c7527c7131c3c42d3f475eb2303c82d4fc3276d6811db37efeb148723082d9b08f79f97c1e5729109a9a28307cc622d2d6cdf52b2b24efe548dedb00142009862cfa879ee1a71f6cec928353511472fbf4389148b0b0e0c108081412458dfe21c9f11351e67e7358595468246d1d1e5e38a6e9e851bc39d84ab502a669331dafec0d8ec7e3e8cb06e1a881d727d1ae40180a434a8c9db129a54126ad48a7358c2b4c5352c8c374bcccdab2bb37d8719cba79fab8211f9df218e0582c261e95f8bfc04f1a1e8bc5c4dfe0a190172af6a9690000000049454e44ae426082</data> + </image> + <image name="image2"> + <data format="PNG" length="1003">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000003b249444154388db5944d4c5c5518869f73ce9db9cc40f929cc30300e18129a50685268a28291982e1a2175212eaab1c49d3f8971e7aec6aedb54a32b435dd8685cb8c0c4b8b0feb421b7bd8186a069d23209144b18cb0c02f3732ff3c3ccbdd705a571941213f1dd9d93739ef37e6fbeef08d334d9d5d0d090c701c8344d2176c1a6697a5d5d5dd8b64d2a95c2b2ac7f05b12c8b783c8e6118d8b6fd685fdb753a39394928e2a7c55724d693a7e214104220242805520a84d8b9e4790f0b1302c7751958f1e30534be9fa41a0c60db362dbe227f64af91b6e7719c2dfc0117a71c603da591de2882a7d3d4ec27122b10acad50aeb88044d542b84de3af7ab44aa55274f4e449dbf354bc347aa096fbf37e7efa2ecbad1b36907d78b289de8120232f37726250c3f52cf0a026a0f6065b9645d929e038167aa096d91b307171059034b5f8e9e9eb44fa052b4b25eeccd9dc99cb71f6ad082fbea2e351c075bdbdc13b9109fc01b83fef63e2e232e03076b68393231a0dcd024daf502c1e66e67a89cb971ef0e5a74bb4b61e6378248094b92ab0ac024b70ca017ef8360394187b2dc6d8b89ffa500e4d4f93d9083275d5e6f9913ade3dd70ee87c7d25c95646a25415aadab152b09ed4f8c5cc130a853839eac3951b684a61e70ef3f9c739668c24eba912afbfddc6d4d506e6a6d7b8b7d082aa8eb8dab19482cdcd220e36dd3dc19df23545de0a71f952861923493456cfd3cf36123c54a0b7bf0e8064621b21f7712c040857071ca4eea0f40a99f510573ec971cb48030e811a1faded3e94be85f2fb00703d1ff26f96ab9f011a5b04d0c4f26fdb948a754c1b25668c2491483d5d5d611617d6b8f0fe32cb779b492ce65168b4c774a4701eefd8f3a02d56e6e8f13aeefe9a63fa5a89d1970e91d908f3d46003e1480d173e28b37827c9b977348ab92ce16890237d1ec907ee3e8e3d8f60d0e1f4583d009f7d9860662acff89bad1c1faad0717493f7ce7713ed8cb0995c255f2a317a26427b67198f6a70f51c0a41b902279ed1187f23cc17130b7c74de65eac77a7a8f05517e41e2deefa4930576db60fa7a8ee1535134df3e93e7b82e0817476439fd6a9070a49f6fbe4a3077739db99b15c001146dd13a46cf1cc1f83943c62e51de76b0738fc9381e8f3390f0236b252e124999e11724fd833196164bacadb87848224fe874f779b43fe9f2dca928956d505a96dbb3f9bdc18661e00534c26d1a7a40e13912a11c9454280da41048a9915c75585df500074d53d816dc9edd229528ef0db66dbbea3ffdaffa471f1f28d8344df1bf800f1a6e9aa6f813c39885bc050f269c0000000049454e44ae426082</data> + </image> +</images> +<tqlayoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/chalk/ui/wdgnewimage.ui b/chalk/ui/wdgnewimage.ui new file mode 100644 index 00000000..5e3b89a6 --- /dev/null +++ b/chalk/ui/wdgnewimage.ui @@ -0,0 +1,435 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>WdgNewImage</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>WdgNewImage</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>572</width> + <height>595</height> + </rect> + </property> + <property name="caption"> + <string>New Image</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>lblName</cstring> + </property> + <property name="text"> + <string>&Name:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>txtName</cstring> + </property> + </widget> + <widget class="TQLineEdit"> + <property name="name"> + <cstring>txtName</cstring> + </property> + <property name="text"> + <string>untitled-1</string> + </property> + </widget> + <widget class="TQGroupBox"> + <property name="name"> + <cstring>grpImage</cstring> + </property> + <property name="title"> + <string>&Image Size</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="1" column="0"> + <property name="name"> + <cstring>lblHeight</cstring> + </property> + <property name="text"> + <string>&Height:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>intHeight</cstring> + </property> + </widget> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>lblWidth</cstring> + </property> + <property name="text"> + <string>&Width:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>intWidth</cstring> + </property> + </widget> + <widget class="KIntNumInput" row="0" column="1"> + <property name="name"> + <cstring>intWidth</cstring> + </property> + <property name="value"> + <number>1600</number> + </property> + <property name="minValue"> + <number>0</number> + </property> + </widget> + <widget class="KIntNumInput" row="1" column="1"> + <property name="name"> + <cstring>intHeight</cstring> + </property> + <property name="value"> + <number>1200</number> + </property> + <property name="minValue"> + <number>0</number> + </property> + </widget> + <widget class="TQLabel" row="0" column="2"> + <property name="name"> + <cstring>lblResolution</cstring> + </property> + <property name="text"> + <string>&Resolution:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>doubleResolution</cstring> + </property> + </widget> + <widget class="KDoubleSpinBox" row="0" column="3"> + <property name="name"> + <cstring>doubleResolution</cstring> + </property> + <property name="suffix"> + <string> dpi</string> + </property> + <property name="maxValue"> + <number>500</number> + </property> + <property name="minValue"> + <number>1</number> + </property> + <property name="lineStep"> + <number>10</number> + </property> + <property name="value"> + <number>100</number> + </property> + </widget> + <spacer row="0" column="4" rowspan="2" colspan="1"> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>131</width> + <height>61</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="TQGroupBox"> + <property name="name"> + <cstring>grpMode</cstring> + </property> + <property name="title"> + <string>Mode</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>lblColorSpaces</cstring> + </property> + <property name="text"> + <string>Color space:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cmbColorSpaces</cstring> + </property> + </widget> + <widget class="KisCmbIDList" row="0" column="1"> + <property name="name"> + <cstring>cmbColorSpaces</cstring> + </property> + </widget> + <widget class="SqueezedComboBox" row="1" column="1"> + <property name="name"> + <cstring>cmbProfile</cstring> + </property> + </widget> + <widget class="TQLabel" row="1" column="0"> + <property name="name"> + <cstring>lblProfiles</cstring> + </property> + <property name="text"> + <string>Profile:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cmbProfile</cstring> + </property> + </widget> + </grid> + </widget> + <widget class="TQGroupBox"> + <property name="name"> + <cstring>grpContents</cstring> + </property> + <property name="title"> + <string>Contents</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQTextEdit" row="2" column="1"> + <property name="name"> + <cstring>txtDescription</cstring> + </property> + </widget> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>lblColor</cstring> + </property> + <property name="text"> + <string>Canvas color:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cmbColor</cstring> + </property> + </widget> + <widget class="KColorCombo" row="0" column="1"> + <property name="name"> + <cstring>cmbColor</cstring> + </property> + </widget> + <widget class="TQLabel" row="2" column="0"> + <property name="name"> + <cstring>lblDescription</cstring> + </property> + <property name="text"> + <string>Description:</string> + </property> + <property name="tqalignment"> + <set>AlignTop</set> + </property> + <property name="buddy" stdset="0"> + <cstring>txtDescription</cstring> + </property> + </widget> + <widget class="TQLabel" row="1" column="0"> + <property name="name"> + <cstring>lblOpacity</cstring> + </property> + <property name="text"> + <string>Opacity:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>sliderOpacity</cstring> + </property> + </widget> + <widget class="TQFrame" row="1" column="1"> + <property name="name"> + <cstring>opacityPanel</cstring> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>Plain</enum> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Transparent</string> + </property> + </widget> + <widget class="TQSlider"> + <property name="name"> + <cstring>sliderOpacity</cstring> + </property> + <property name="maxValue"> + <number>100</number> + </property> + <property name="pageStep"> + <number>10</number> + </property> + <property name="value"> + <number>100</number> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="tickmarks"> + <enum>Below</enum> + </property> + <property name="tickInterval"> + <number>20</number> + </property> + <property name="toolTip" stdset="0"> + <string>Opacity of the background color.</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Opacity of the background color.</string> + </property> + </widget> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="text"> + <string>Opaque</string> + </property> + </widget> + </hbox> + </widget> + </grid> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>480</width> + <height>21</height> + </size> + </property> + </spacer> + <widget class="TQPushButton"> + <property name="name"> + <cstring>m_createButton</cstring> + </property> + <property name="text"> + <string>Create</string> + </property> + </widget> + </hbox> + </widget> + <spacer> + <property name="name"> + <cstring>spacer3</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>21</width> + <height>0</height> + </size> + </property> + </spacer> + </vbox> +</widget> +<customwidgets> + <customwidget> + <class>KisCmbIDList</class> + <header location="local">kis_cmb_idlist.h</header> + <sizehint> + <width>1</width> + <height>24</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image0</pixmap> + </customwidget> + <customwidget> + <class>SqueezedComboBox</class> + <header location="local">squeezedcombobox.h</header> + <sizehint> + <width>-1</width> + <height>32</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>3</hordata> + <verdata>0</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image1</pixmap> + </customwidget> +</customwidgets> +<images> + <image name="image0"> + <data format="PNG" length="870">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000032d49444154388db59531681c4714863f892dde8004b320c32e3870020b74458a6b0f5458e581c016a809a8496b42208454098604d2c4904a6954a410511ae752085b858c1208dc35221244b00119f60ac12ee860062c980719708a95a248f129459cd7cceeccf0edb76fff61a706830197d5ed765ff3166a30184c4d5d829fed3c7bdd5e6ce3bda71a5738ef301802e1d6d179477152303c1842bc822797a64fbf7b4a9a43be00ada817cb0e12011c2611205ccd73755f9c087c6b19bef0d7c100f5b8267d07caf10fe8ab9210156320fc01be16aa5a11043307f30b20a21041019985f48ef2f7fa0becc68e80475fd584e831b396f210f67795c3831a4940a3228925bb27f4d652ba4b01a199b73342f3981be0ca57745042ac30c632d853b6373d44b056c8ef0922508d94d14be59b2f4aeaf58cd5751069e06f3436890114332b9487d0bf80f61e64dc5f813c3790045453f67703fd4d4f7f6b4496b5597e689044af194f5f5e841800210478bee3d1a8f41e64acbe0f69ae6852e1cf0ccf7f74f4d652defbc042226c6f55e8f89f91bb6e9c387c9d521c9558db988a3416fe3c67e32b4779ec7167f0e8939ce19ea7fc5d298a80c875f03563930855ed2081bc05e91d5014ef53363eaf288e3d6285ee520a338e76c7a251a94e41e30470d3631004a262672e3eca59cec6978ef2b889979d11f2bb904af3be92081a416e28dfe831983920b1142345d5b0ff2234a6334276d7321ad53c795c511ca654a5a251996f19b83d158ef602b45a423d52f67703abeb29ee4ce9de4fc93378f218462f6b3efdb042cf3d59666977a0aa6fe9310888d25b13342afd4dcffeaee3d147399da540ab13f8f8b39c2cb3f8710d11ba2b96f9c57fcd7180287497a03ecde86f8dd8fe1a867b9ef6bb1612a84a871f6bd35b94e217a53832589970f2dcd85d9c7d4580d57521cbdaf4bfaf288e95e268d4ec8e60e72ccb0f2dbffea454e71e8d29f57882717152509482a48d8924b0bc12e82ee51445a03a6da079cbd0eec0fc22142b06620e89a3fc8d3783870743d814d2bc8994aa6ff286472e764902e5a96f72bbd3b4c37b280e95aa9e604c84e1cf978b37c74935797d7ae2ca7fac6968fe51ff0bf86dc30783c1d49f0baa9bb819e612310000000049454e44ae426082</data> + </image> + <image name="image1"> + <data format="PNG" length="1003">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000003b249444154388db5944d4c5c5518869f73ce9db9cc40f929cc30300e18129a50685268a28291982e1a2175212eaab1c49d3f8971e7aec6aedb54a32b435dd8685cb8c0c4b8b0feb421b7bd8186a069d23209144b18cb0c02f3732ff3c3ccbdd705a571941213f1dd9d93739ef37e6fbeef08d334d9d5d0d090c701c8344d2176c1a6697a5d5d5dd8b64d2a95c2b2ac7f05b12c8b783c8e6118d8b6fd685fdb753a39394928e2a7c55724d693a7e214104220242805520a84d8b9e4790f0b1302c7751958f1e30534be9fa41a0c60db362dbe227f64af91b6e7719c2dfc0117a71c603da591de2882a7d3d4ec27122b10acad50aeb88044d542b84de3af7ab44aa55274f4e449dbf354bc347aa096fbf37e7efa2ecbad1b36907d78b289de8120232f37726250c3f52cf0a026a0f6065b9645d929e038167aa096d91b307171059034b5f8e9e9eb44fa052b4b25eeccd9dc99cb71f6ad082fbea2e351c075bdbdc13b9109fc01b83fef63e2e232e03076b68393231a0dcd024daf502c1e66e67a89cb971ef0e5a74bb4b61e6378248094b92ab0ac024b70ca017ef8360394187b2dc6d8b89ffa500e4d4f93d9083275d5e6f9913ade3dd70ee87c7d25c95646a25415aadab152b09ed4f8c5cc130a853839eac3951b684a61e70ef3f9c739668c24eba912afbfddc6d4d506e6a6d7b8b7d082aa8eb8dab19482cdcd220e36dd3dc19df23545de0a71f952861923493456cfd3cf36123c54a0b7bf0e8064621b21f7712c040857071ca4eea0f40a99f510573ec971cb48030e811a1faded3e94be85f2fb00703d1ff26f96ab9f011a5b04d0c4f26fdb948a754c1b25668c2491483d5d5d611617d6b8f0fe32cb779b492ce65168b4c774a4701eefd8f3a02d56e6e8f13aeefe9a63fa5a89d1970e91d908f3d46003e1480d173e28b37827c9b977348ab92ce16890237d1ec907ee3e8e3d8f60d0e1f4583d009f7d9860662acff89bad1c1faad0717493f7ce7713ed8cb0995c255f2a317a26427b67198f6a70f51c0a41b902279ed1187f23cc17130b7c74de65eac77a7a8f05517e41e2deefa4930576db60fa7a8ee1535134df3e93e7b82e0817476439fd6a9070a49f6fbe4a3077739db99b15c001146dd13a46cf1cc1f83943c62e51de76b0738fc9381e8f3390f0236b252e124999e11724fd833196164bacadb87848224fe874f779b43fe9f2dca928956d505a96dbb3f9bdc18661e00534c26d1a7a40e13912a11c9454280da41048a9915c75585df500074d53d816dc9edd229528ef0db66dbbea3ffdaffa471f1f28d8344df1bf800f1a6e9aa6f813c39885bc050f269c0000000049454e44ae426082</data> + </image> +</images> +<tabstops> + <tabstop>txtName</tabstop> + <tabstop>intWidth</tabstop> + <tabstop>intHeight</tabstop> + <tabstop>doubleResolution</tabstop> + <tabstop>cmbColorSpaces</tabstop> + <tabstop>cmbProfile</tabstop> + <tabstop>cmbColor</tabstop> + <tabstop>sliderOpacity</tabstop> + <tabstop>txtDescription</tabstop> +</tabstops> +<tqlayoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>kis_cmb_idlist.h</includehint> + <includehint>squeezedcombobox.h</includehint> + <includehint>kcolorcombo.h</includehint> +</includehints> +</UI> diff --git a/chalk/ui/wdgpalettechooser.ui b/chalk/ui/wdgpalettechooser.ui new file mode 100644 index 00000000..553cd62b --- /dev/null +++ b/chalk/ui/wdgpalettechooser.ui @@ -0,0 +1,105 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>KisPaletteChooser</class> +<widget class="TQDialog"> + <property name="name"> + <cstring>KisPaletteChooser</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>289</width> + <height>163</height> + </rect> + </property> + <property name="caption"> + <string>Choose Palette</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQListBox"> + <property name="name"> + <cstring>paletteList</cstring> + </property> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>255</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="TQPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="TQPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>KisPaletteChooser</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>KisPaletteChooser</receiver> + <slot>reject()</slot> + </connection> +</connections> +<tqlayoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/chalk/ui/wdgperformancesettings.ui b/chalk/ui/wdgperformancesettings.ui new file mode 100644 index 00000000..0bce88e9 --- /dev/null +++ b/chalk/ui/wdgperformancesettings.ui @@ -0,0 +1,146 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>WdgPerformanceSettings</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>WdgPerformanceSettings</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>495</width> + <height>220</height> + </rect> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Maximum number of tiles kept in memory:</string> + </property> + <property name="whatsThis" stdset="0"> + <string>The maximum number of "tiles" that are kept in memory. For regular RGBA8 images, each tile is about 16 kB in size. Thus, for a value of 500 tiles this usually means about 8 megabytes are used for image data. If you regularly handle large images, a greater value here might be useful. +Note that this number is only a guideline for Chalk, and is not guaranteed to be the actual number of tiles in memory.</string> + </property> + </widget> + <widget class="KIntNumInput"> + <property name="name"> + <cstring>m_maxTiles</cstring> + </property> + <property name="value"> + <number>500</number> + </property> + <property name="minValue"> + <number>0</number> + </property> + <property name="whatsThis" stdset="0"> + <string>The maximum number of "tiles" that are kept in memory. For regular RGBA8 images, each tile is about 16 kB in size. Thus, for a value of 500 tiles this usually means about 8 megabytes are used for image data. If you regularly handle large images, a greater value here might be useful. +Note that this number is only a guideline for Chalk, and is not guaranteed to be the actual number of tiles in memory.</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>81</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout5</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="text"> + <string>Swappiness:</string> + </property> + <property name="whatsThis" stdset="0"> + <string>This configures how much Chalk will use the swap file. If you move the slider all the way to the left, Chalk will not use the swap file at all. If you move it all the way to the right, Chalk will make maximum use of the swap file.</string> + </property> + </widget> + <widget class="TQSlider"> + <property name="name"> + <cstring>m_swappiness</cstring> + </property> + <property name="tqmaximumSize"> + <size> + <width>600</width> + <height>32767</height> + </size> + </property> + <property name="maxValue"> + <number>6</number> + </property> + <property name="value"> + <number>3</number> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="tickmarks"> + <enum>Below</enum> + </property> + <property name="whatsThis" stdset="0"> + <string>This configures how much Chalk likes to swap. Move the slider to the left, and there is no swapping at all. Move it to the right there is a lot of swapping going on.</string> + </property> + </widget> + </hbox> + </widget> + <spacer> + <property name="name"> + <cstring>spacer3</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>20</width> + <height>139</height> + </size> + </property> + </spacer> + </vbox> +</widget> +<customwidgets> +</customwidgets> +<tqlayoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> +</includehints> +</UI> diff --git a/chalk/ui/wdgpressuresettings.ui b/chalk/ui/wdgpressuresettings.ui new file mode 100644 index 00000000..41ead6a9 --- /dev/null +++ b/chalk/ui/wdgpressuresettings.ui @@ -0,0 +1,66 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>WdgPressureSettings</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>WdgPressureSettings</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>510</width> + <height>87</height> + </rect> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="1" column="1"> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>21</width> + <height>89</height> + </size> + </property> + </spacer> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel3</cstring> + </property> + <property name="text"> + <string>Softer</string> + </property> + </widget> + <widget class="TQLabel" row="0" column="2"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="text"> + <string>Firmer</string> + </property> + </widget> + <widget class="TQSlider" row="0" column="1"> + <property name="name"> + <cstring>slPressure</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="tickmarks"> + <enum>NoMarks</enum> + </property> + </widget> + </grid> +</widget> +<tqlayoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/chalk/ui/wdgselectionoptions.ui b/chalk/ui/wdgselectionoptions.ui new file mode 100644 index 00000000..39846fa3 --- /dev/null +++ b/chalk/ui/wdgselectionoptions.ui @@ -0,0 +1,64 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>WdgSelectionOptions</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>WdgSelectionOptions</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>180</width> + <height>34</height> + </rect> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>0</number> + </property> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>lblAction</cstring> + </property> + <property name="text"> + <string>Action:</string> + </property> + </widget> + <widget class="TQComboBox"> + <item> + <property name="text"> + <string>Add</string> + </property> + </item> + <item> + <property name="text"> + <string>Subtract</string> + </property> + </item> + <property name="name"> + <cstring>cmbAction</cstring> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<tqlayoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/chalk/ui/wdgshapeoptions.ui b/chalk/ui/wdgshapeoptions.ui new file mode 100644 index 00000000..c0e6338b --- /dev/null +++ b/chalk/ui/wdgshapeoptions.ui @@ -0,0 +1,98 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>WdgGeometryOptions</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>WdgGeometryOptions</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>275</width> + <height>31</height> + </rect> + </property> + <property name="caption"> + <string>Geometry Options</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>2</number> + </property> + <property name="spacing"> + <number>2</number> + </property> + <spacer row="1" column="2"> + <property name="name"> + <cstring>spacer9</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>20</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel3</cstring> + </property> + <property name="text"> + <string>Fill:</string> + </property> + </widget> + <widget class="TQComboBox" row="0" column="1" rowspan="1" colspan="2"> + <item> + <property name="text"> + <string>Not Filled</string> + </property> + </item> + <item> + <property name="text"> + <string>Foreground Color</string> + </property> + </item> + <item> + <property name="text"> + <string>Background Color</string> + </property> + </item> + <item> + <property name="text"> + <string>Pattern</string> + </property> + </item> + <property name="name"> + <cstring>cmbFill</cstring> + </property> + </widget> + <spacer row="0" column="3" rowspan="2" colspan="1"> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>21</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> +</widget> +<tqlayoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/chalk/ui/wdgtabletdevicesettings.ui b/chalk/ui/wdgtabletdevicesettings.ui new file mode 100644 index 00000000..59cad307 --- /dev/null +++ b/chalk/ui/wdgtabletdevicesettings.ui @@ -0,0 +1,193 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>WdgTabletDeviceSettings</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>WdgTabletDeviceSettings</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>363</width> + <height>386</height> + </rect> + </property> + <property name="caption"> + <string>Configure Tablet Device</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>21</width> + <height>90</height> + </size> + </property> + </spacer> + <widget class="TQGroupBox" row="0" column="0"> + <property name="name"> + <cstring>groupBox3</cstring> + </property> + <property name="title"> + <string>Axes</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel1_2</cstring> + </property> + <property name="text"> + <string>X:</string> + </property> + </widget> + <widget class="TQComboBox"> + <property name="name"> + <cstring>cbX</cstring> + </property> + </widget> + </hbox> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout4_4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel1_2_4</cstring> + </property> + <property name="text"> + <string>Y:</string> + </property> + </widget> + <widget class="TQComboBox"> + <property name="name"> + <cstring>cbY</cstring> + </property> + </widget> + </hbox> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout4_2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel1_2_2</cstring> + </property> + <property name="text"> + <string>Pressure:</string> + </property> + </widget> + <widget class="TQComboBox"> + <property name="name"> + <cstring>cbPressure</cstring> + </property> + </widget> + </hbox> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout4_3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel1_2_3</cstring> + </property> + <property name="text"> + <string>X tilt:</string> + </property> + </widget> + <widget class="TQComboBox"> + <property name="name"> + <cstring>cbXTilt</cstring> + </property> + </widget> + </hbox> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout4_6</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel1_2_6</cstring> + </property> + <property name="text"> + <string>Y tilt:</string> + </property> + </widget> + <widget class="TQComboBox"> + <property name="name"> + <cstring>cbYTilt</cstring> + </property> + </widget> + </hbox> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout4_5</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel1_2_5</cstring> + </property> + <property name="text"> + <string>Wheel:</string> + </property> + </widget> + <widget class="TQComboBox"> + <property name="name"> + <cstring>cbWheel</cstring> + </property> + </widget> + </hbox> + </widget> + </vbox> + </widget> + </grid> +</widget> +<tqlayoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/chalk/ui/wdgtabletsettings.ui b/chalk/ui/wdgtabletsettings.ui new file mode 100644 index 00000000..ad4dc7bf --- /dev/null +++ b/chalk/ui/wdgtabletsettings.ui @@ -0,0 +1,104 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>WdgTabletSettings</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>WdgTabletSettings</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>510</width> + <height>268</height> + </rect> + </property> + <property name="caption"> + <string>Tablet</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQGroupBox" row="1" column="0"> + <property name="name"> + <cstring>grpTabletDevices</cstring> + </property> + <property name="title"> + <string>Tablet Devices</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Device:</string> + </property> + </widget> + <widget class="TQComboBox"> + <property name="name"> + <cstring>cbTabletDevice</cstring> + </property> + </widget> + </hbox> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout5</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQCheckBox"> + <property name="name"> + <cstring>chkEnableTabletDevice</cstring> + </property> + <property name="text"> + <string>Enable</string> + </property> + </widget> + <widget class="TQPushButton"> + <property name="name"> + <cstring>btnConfigureTabletDevice</cstring> + </property> + <property name="text"> + <string>Configure...</string> + </property> + </widget> + </hbox> + </widget> + </vbox> + </widget> + <spacer row="2" column="0"> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>21</width> + <height>90</height> + </size> + </property> + </spacer> + </grid> +</widget> +<tqlayoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/chalk/ui/wdgtextbrush.ui b/chalk/ui/wdgtextbrush.ui new file mode 100644 index 00000000..562a62f9 --- /dev/null +++ b/chalk/ui/wdgtextbrush.ui @@ -0,0 +1,158 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>KisWdgTextBrush</class> +<widget class="TQWidget"> + <property name="name"> + <cstring>KisWdgTextBrush</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>317</width> + <height>89</height> + </rect> + </property> + <property name="caption"> + <string>Text</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>tqlayout3</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout9</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>labelText</cstring> + </property> + <property name="text"> + <string>Text:</string> + </property> + </widget> + <widget class="KLineEdit"> + <property name="name"> + <cstring>lineEdit</cstring> + </property> + <property name="tqminimumSize"> + <size> + <width>120</width> + <height>0</height> + </size> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>The Quick Brown Fox Jumps Over The Lazy Dog</string> + </property> + </widget> + </hbox> + </widget> + <widget class="TQLayoutWidget"> + <property name="name"> + <cstring>tqlayout10</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>lblFont</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Font:</string> + </property> + </widget> + <widget class="TQToolButton"> + <property name="name"> + <cstring>bnFont</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="accel"> + <string></string> + </property> + </widget> + </hbox> + </widget> + </vbox> + </widget> + <spacer row="0" column="1"> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Minimum</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>121</width> + <height>20</height> + </size> + </property> + </spacer> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Minimum</enum> + </property> + <property name="tqsizeHint"> + <size> + <width>20</width> + <height>31</height> + </size> + </property> + </spacer> + </grid> +</widget> +<customwidgets> +</customwidgets> +<Q_SLOTS> + <slot access="private">boldButtonClicked()</slot> +</Q_SLOTS> +<tqlayoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>klineedit.h</includehint> +</includehints> +</UI> |