You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ktechlab/src/canvasitemparts.cpp

554 lines
12 KiB

/***************************************************************************
* Copyright (C) 2003-2005 by David Saxton *
* david@bluehaze.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. *
***************************************************************************/
#include "canvasitemparts.h"
#include "cells.h"
#include "cnitem.h"
#include "icndocument.h"
#include <tqpainter.h>
//BEGIN Class GuiPart
GuiPart::GuiPart( CNItem *parent, const TQRect & r, TQCanvas * canvas )
: TQObject(parent),
TQCanvasRectangle( r, canvas ),
m_angleDegrees(0),
p_parent(parent),
b_pointsAdded(false),
m_originalRect(r)
{
connect( parent, TQ_SIGNAL(movedBy(double, double )), this, TQ_SLOT(slotMoveBy(double, double )) );
setZ( parent->z() + 0.5 );
}
GuiPart::~GuiPart()
{
hide();
}
void GuiPart::setAngleDegrees( int angleDegrees )
{
m_angleDegrees = angleDegrees;
posChanged();
if (canvas())
canvas()->setChanged( boundingRect() );
}
void GuiPart::setGuiPartSize( int width, int height )
{
updateConnectorPoints(false);
setSize( width, height );
posChanged();
}
void GuiPart::initPainter( TQPainter &p )
{
if ( (m_angleDegrees%180) == 0 )
return;
p.translate( int(x()+(width()/2)), int(y()+(height()/2)) );
p.rotate(m_angleDegrees);
p.translate( -int(x()+(width()/2)), -int(y()+(height()/2)) );
}
void GuiPart::deinitPainter( TQPainter &p )
{
if ( (m_angleDegrees%180) == 0 )
return;
p.translate( int(x()+(width()/2)), int(y()+(height()/2)) );
p.rotate(-m_angleDegrees);
p.translate( -int(x()+(width()/2)), -int(y()+(height()/2)) );
}
void GuiPart::slotMoveBy( double dx, double dy )
{
if ( dx==0 && dy==0 )
return;
moveBy( dx, dy );
posChanged();
}
void GuiPart::updateConnectorPoints( bool add )
{
ICNDocument *icnd = dynamic_cast<ICNDocument*>(p_parent->itemDocument());
if ( !icnd)
return;
Cells * cells = icnd->cells();
if (!cells)
return;
if ( add == b_pointsAdded )
return;
b_pointsAdded = add;
int mult = add ? 1 : -1;
int sx = int(x()/8);
int sy = int(y()/8);
int ex = int((x()+width())/8);
int ey = int((y()+height())/8);
for ( int x=sx; x<=ex; ++x )
{
for ( int y=sy; y<=ey; ++y )
{
if ( icnd->isValidCellReference( x, y ) )
(*cells)[x][y].CIpenalty += mult*ICNDocument::hs_item/2;
}
}
}
TQRect GuiPart::drawRect()
{
TQRect dr = rect();
if ( m_angleDegrees%180 != 0 )
{
TQWMatrix m;
m.translate( int(x()+(width()/2)), int(y()+(height()/2)) );
if ( (m_angleDegrees%180) != 0 )
m.rotate(-m_angleDegrees);
m.translate( -int(x()+(width()/2)), -int(y()+(height()/2)) );
dr = m.mapRect(dr);
}
return dr;
}
//END Class GuiPart
//BEGIN Class Text
Text::Text( const TQString &text, CNItem *parent, const TQRect & r, TQCanvas * canvas, int flags )
: GuiPart( parent, r, canvas )
{
m_flags = flags;
setText(text);
}
Text::~Text()
{
}
bool Text::setText( const TQString & text )
{
if ( m_text == text )
return false;
updateConnectorPoints(false);
m_text = text;
return true;
}
void Text::setFlags( int flags )
{
updateConnectorPoints( false );
m_flags = flags;
}
void Text::drawShape( TQPainter & p )
{
initPainter(p);
p.setFont( p_parent->font() );
p.drawText( drawRect(), m_flags, m_text );
deinitPainter(p);
}
TQRect Text::recommendedRect() const
{
return TQFontMetrics( p_parent->font() ).boundingRect( m_originalRect.x(), m_originalRect.y(), m_originalRect.width(), m_originalRect.height(), m_flags, m_text );
}
//END Class Text
//BEGIN Class Widget
Widget::Widget( const TQString & id, CNItem * parent, const TQRect & r, TQCanvas * canvas )
: GuiPart( parent, r, canvas )
{
m_id = id;
show();
}
Widget::~Widget()
{
}
int Widget::rtti() const
{
return ItemDocument::RTTI::Widget;
}
void Widget::setEnabled( bool enabled )
{
widget()->setEnabled(enabled);
}
void Widget::posChanged()
{
// Swap around the width / height if we are rotated at a non-half way around
if ( m_angleDegrees%90 != 0 )
widget()->setFixedSize( TQSize( height(), width() ) );
else
widget()->setFixedSize( size() );
widget()->move( int(x()), int(y()) );
}
void Widget::drawShape( TQPainter &p )
{
// initPainter(p);
p.drawPixmap( int(x()), int(y()), TQPixmap::grabWidget( widget() ) );
// deinitPainter(p);
}
//END Class Widget
//BEGIN Class ToolButton
ToolButton::ToolButton( TQWidget *parent )
: TQToolButton(parent)
{
m_angleDegrees = 0;
if ( TQFontInfo(m_font).pixelSize() > 11 ) // It has to be > 11, not > 12, as (I think) pixelSize() rounds off the actual size
m_font.setPixelSize(12);
}
void ToolButton::drawButtonLabel( TQPainter * p )
{
if ( m_angleDegrees % 180 == 0 || text().isEmpty() )
{
TQToolButton::drawButtonLabel(p);
return;
}
double dx = size().width()/2;
double dy = size().height()/2;
p->translate( dx, dy );
p->rotate( m_angleDegrees );
p->translate( -dx, -dy );
p->translate( -dy+dx, 0 );
int m = width() > height() ? width() : height();
p->setPen( TQt::black );
p->drawText( isDown()?1:0, isDown()?1:0, m, m, TQt::AlignVCenter | TQt::AlignHCenter, text() );
p->translate( dy-dx, 0 );
p->translate( dx, dy );
p->rotate( -m_angleDegrees );
p->translate( -dx, -dy );
}
//END Class ToolButton
//BEGIN Class Button
Button::Button( const TQString & id, CNItem * parent, bool isToggle, const TQRect & r, TQCanvas * canvas )
: Widget( id, parent, r, canvas )
{
b_isToggle = isToggle;
m_button = new ToolButton(0l);
m_button->setUsesTextLabel(false);
m_button->setToggleButton(b_isToggle);
connect( m_button, TQ_SIGNAL(pressed()), this, TQ_SLOT(slotStateChanged()) );
connect( m_button, TQ_SIGNAL(released()), this, TQ_SLOT(slotStateChanged()) );
posChanged();
}
Button::~Button()
{
delete m_button;
}
void Button::setToggle( bool toggle )
{
if ( b_isToggle == toggle )
return;
if (b_isToggle)
{
// We must first untoggle it, else it'll be forever stuck...
setState(false);
}
b_isToggle = toggle;
m_button->setToggleButton(b_isToggle);
}
void Button::posChanged()
{
Widget::posChanged();
m_button->setAngleDegrees(m_angleDegrees);
}
void Button::slotStateChanged()
{
parent()->buttonStateChanged( id(), m_button->isDown() || m_button->isOn() );
}
TQWidget* Button::widget() const
{
return m_button;
}
void Button::setPixmap( const TQPixmap &p )
{
m_button->setPixmap(p);
}
void Button::setState( bool state )
{
if ( this->state() == state )
return;
if ( isToggle() )
m_button->setOn(state);
else
m_button->setDown(state);
slotStateChanged();
}
bool Button::state() const
{
if ( isToggle() )
return m_button->state();
else
return m_button->isDown();
}
TQRect Button::recommendedRect() const
{
TQSize sizeHint = m_button->sizeHint();
if ( sizeHint.width() < m_originalRect.width() )
sizeHint.setWidth( m_originalRect.width() );
// Hmm...for now, lets just keep the recomended rect the same height as the original rect
sizeHint.setHeight( m_originalRect.height() );
int hdw = (sizeHint.width() - m_originalRect.width())/2;
int hdh = (sizeHint.height() - m_originalRect.height())/2;
return TQRect( m_originalRect.x()-hdw, m_originalRect.y()-hdh, sizeHint.width(), sizeHint.height() );
}
void Button::setText( const TQString &text )
{
if ( m_button->text() == text )
return;
updateConnectorPoints(false);
m_button->setUsesTextLabel(true);
m_button->setText(text);
m_button->setTextLabel(text);
canvas()->setChanged( rect() );
p_parent->updateAttachedPositioning();
}
void Button::mousePressEvent( TQMouseEvent *e )
{
if ( !m_button->isEnabled() )
return;
TQMouseEvent event( TQEvent::MouseButtonPress, e->pos()-TQPoint(int(x()),int(y())), e->button(), e->state() );
m_button->mousePressEvent(&event);
if (event.isAccepted())
e->accept();
canvas()->setChanged( rect() );
}
void Button::mouseReleaseEvent( TQMouseEvent *e )
{
TQMouseEvent event( TQEvent::MouseButtonRelease, e->pos()-TQPoint(int(x()),int(y())), e->button(), e->state() );
m_button->mouseReleaseEvent(&event);
if (event.isAccepted())
e->accept();
canvas()->setChanged( rect() );
}
void Button::enterEvent()
{
m_button->enterEvent();
// m_button->setFocus();
// bool hasFocus = m_button->hasFocus();
// m_button->setAutoRaise(true);
// m_button->setOn(true);
}
void Button::leaveEvent()
{
m_button->leaveEvent();
// m_button->clearFocus();
// bool hasFocus = m_button->hasFocus();
// m_button->setAutoRaise(false);
// m_button->setOn(false);
}
//END Class Button
//BEGIN Class SliderWidget
SliderWidget::SliderWidget( TQWidget *parent )
: TQSlider(parent)
{
setWFlags(WNoAutoErase|WRepaintNoErase);
}
//END Class SliderWidget
//BEGIN Class Slider
Slider::Slider( const TQString & id, CNItem * parent, const TQRect & r, TQCanvas * canvas )
: Widget( id, parent, r, canvas )
{
m_orientation = TQt::Vertical;
m_slider = new SliderWidget(0l);
m_slider->setPaletteBackgroundColor(TQt::white);
m_slider->setPaletteForegroundColor(TQt::white);
m_slider->setEraseColor(TQt::white);
m_slider->setBackgroundMode( TQt::NoBackground );
connect( m_slider, TQ_SIGNAL(valueChanged(int)), this, TQ_SLOT(slotValueChanged(int)) );
posChanged();
}
Slider::~Slider()
{
delete m_slider;
}
TQWidget* Slider::widget() const
{
return m_slider;
}
int Slider::value() const
{
return m_slider->value();
}
void Slider::setValue( int value )
{
m_slider->setValue(value);
}
void Slider::mousePressEvent( TQMouseEvent *e )
{
TQMouseEvent event( TQEvent::MouseButtonPress, e->pos()-TQPoint(int(x()),int(y())), e->button(), e->state() );
m_slider->mousePressEvent(&event);
if (event.isAccepted())
e->accept();
canvas()->setChanged( rect() );
}
void Slider::mouseReleaseEvent( TQMouseEvent *e )
{
TQMouseEvent event( TQEvent::MouseButtonRelease, e->pos()-TQPoint(int(x()),int(y())), e->button(), e->state() );
m_slider->mouseReleaseEvent(&event);
if (event.isAccepted())
e->accept();
canvas()->setChanged( rect() );
}
void Slider::mouseDoubleClickEvent ( TQMouseEvent *e )
{
TQMouseEvent event( TQEvent::MouseButtonDblClick, e->pos()-TQPoint(int(x()),int(y())), e->button(), e->state() );
m_slider->mouseDoubleClickEvent(&event);
if (event.isAccepted())
e->accept();
canvas()->setChanged( rect() );
}
void Slider::mouseMoveEvent( TQMouseEvent *e )
{
TQMouseEvent event( TQEvent::MouseMove, e->pos()-TQPoint(int(x()),int(y())), e->button(), e->state() );
m_slider->mouseMoveEvent(&event);
if (event.isAccepted())
e->accept();
}
void Slider::wheelEvent( TQWheelEvent *e )
{
TQWheelEvent event( e->pos()-TQPoint(int(x()),int(y())), e->delta(), e->state(), e->orientation() );
m_slider->wheelEvent(&event);
if (event.isAccepted())
e->accept();
canvas()->setChanged( rect() );
}
void Slider::enterEvent()
{
m_slider->enterEvent();
}
void Slider::leaveEvent()
{
m_slider->leaveEvent();
}
void Slider::slotValueChanged( int value )
{
parent()->itemDocument()->setModified(true);
parent()->sliderValueChanged(id(),value);
}
void Slider::setOrientation( TQt::Orientation o )
{
m_orientation = o;
posChanged();
}
void Slider::posChanged()
{
Widget::posChanged();
if ( m_orientation == TQt::Vertical )
m_slider->setOrientation( (m_angleDegrees%180 == 0) ? TQt::Vertical : TQt::Horizontal );
else
m_slider->setOrientation( (m_angleDegrees%180 == 0) ? TQt::Horizontal : TQt::Vertical );
}
//END Class Slider
#include "canvasitemparts.moc"