package CharacterWidget; use strict; use warnings; use List::Util qw( max ); use QtCore4; use QtGui4; use QtCore4::isa qw( Qt::Widget ); use QtCore4::slots updateFont => ['QFont'], updateSize => ['QString'], updateStyle => ['QString'], updateFontMerging => ['bool']; use QtCore4::signals characterSelected => ['QString']; sub displayFont() { return this->{displayFont}; } sub columns() { return this->{columns}; } sub lastKey() { return this->{lastKey}; } sub squareSize() { return this->{squareSize}; } sub setDisplayFont() { return this->{displayFont} = shift; } sub setColumns() { return this->{columns} = shift; } sub setLastKey() { return this->{lastKey} = shift; } sub setSquareSize() { return this->{squareSize} = shift; } # [0] sub NEW { my ( $class, $parent ) = @_; $class->SUPER::NEW( $parent ); this->setSquareSize( 24 ); this->setColumns( 16 ); this->setLastKey( -1 ); this->setDisplayFont( Qt::Font() ); this->setMouseTracking(1); } # [0] # [1] sub updateFont { my ($font) = @_; this->displayFont->setFamily($font->family()); this->setSquareSize( max(24, Qt::FontMetrics(this->displayFont)->xHeight() * 3) ); this->adjustSize(); this->update(); } # [1] # [2] sub updateSize { my ($fontSize) = @_; this->displayFont->setPointSize($fontSize); this->setSquareSize( max(24, Qt::FontMetrics(displayFont)->xHeight() * 3) ); this->adjustSize(); this->update(); } # [2] sub updateStyle { my ($fontStyle) = @_; my $fontDatabase = Qt::FontDatabase(); my $oldStrategy = this->displayFont->styleStrategy(); this->setDisplayFont( $fontDatabase->font(this->displayFont->family(), $fontStyle, this->displayFont->pointSize()) ); this->displayFont->setStyleStrategy($oldStrategy); this->setSquareSize( max(24, Qt::FontMetrics(displayFont)->xHeight() * 3) ); this->adjustSize(); this->update(); } sub updateFontMerging { my ($enable) = @_; if ($enable) { this->displayFont->setStyleStrategy(Qt::Font::PreferDefault()); } else { this->displayFont->setStyleStrategy(Qt::Font::NoFontMerging()); } this->adjustSize(); this->update(); } # [3] sub sizeHint { return Qt::Size(this->columns*this->squareSize, (65536/this->columns)*this->squareSize); } # [3] # [4] sub mouseMoveEvent { my ($event) = @_; my $widgetPosition = this->mapFromGlobal($event->globalPos()); my $key = sprintf '%d', (sprintf '%d', $widgetPosition->y()/this->squareSize)*this->columns + $widgetPosition->x()/this->squareSize; my $char = chr($key); utf8::upgrade($char); my $text = sprintf( "<p>Character: <span style=\"font-size: 24pt; font-family: %s\">", this->displayFont->family() ) . $char . "</span><p>Value: 0x" . sprintf( '%x', $key ); Qt::ToolTip::showText($event->globalPos(), $text, this); } # [4] # [5] sub mousePressEvent { my ($event) = @_; if ($event->button() == Qt::LeftButton()) { this->setLastKey( sprintf '%d', (sprintf '%d', $event->y()/this->squareSize)*this->columns + $event->x()/this->squareSize ); if (Qt::Char(this->lastKey)->category() != Qt::Char::NoCategory()) { my $char = chr(this->lastKey); utf8::upgrade($char); emit this->characterSelected($char); } this->update(); } else { this->SUPER::mousePressEvent($event); } } # [5] # [6] sub paintEvent { my ($event) = @_; my $squareSize = this->squareSize; my $painter = Qt::Painter(this); $painter->fillRect($event->rect(), Qt::Brush(Qt::white())); $painter->setFont(this->displayFont); # [6] # [7] my $redrawRect = $event->rect(); my $beginRow = sprintf '%d', $redrawRect->top()/$squareSize; my $endRow = sprintf '%d', $redrawRect->bottom()/$squareSize; my $beginColumn = sprintf '%d', $redrawRect->left()/$squareSize; my $endColumn = sprintf '%d', $redrawRect->right()/$squareSize; # [7] # [8] $painter->setPen(Qt::Color(Qt::gray())); for (my $row = $beginRow; $row <= $endRow; ++$row) { for (my $column = $beginColumn; $column <= $endColumn; ++$column) { $painter->drawRect($column*$squareSize, $row*$squareSize, $squareSize, $squareSize); } # [8] //! [9] } # [9] # [10] my $fontMetrics = Qt::FontMetrics(this->displayFont); $painter->setPen(Qt::Color(Qt::black())); for (my $row = $beginRow; $row <= $endRow; ++$row) { for (my $column = $beginColumn; $column <= $endColumn; ++$column) { my $key = $row*this->columns + $column; $painter->setClipRect($column*$squareSize, $row*$squareSize, $squareSize, $squareSize); if ($key == this->lastKey) { $painter->fillRect($column*$squareSize + 1, $row*$squareSize + 1, $squareSize, $squareSize, Qt::Brush(Qt::red())); } my $char = chr($key); utf8::upgrade($char); $painter->drawText($column*$squareSize + ($squareSize / 2) - $fontMetrics->width(Qt::Char(Qt::Int($key)))/2, $row*$squareSize + 4 + $fontMetrics->ascent(), $char); } } $painter->end(); } # [10] 1;