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.
275 lines
8.2 KiB
275 lines
8.2 KiB
#!/usr/bin/env ruby -w
|
|
|
|
#
|
|
# A class that lets the user draw with the mouse. The
|
|
# window knows how to redraw itself.
|
|
#
|
|
|
|
require 'Qt'
|
|
|
|
class ScribbleArea < TQt::Widget
|
|
|
|
slots "setColor(TQColor)", "slotLoad(const TQString&)", "slotSave(const TQString&)", "slotClearArea()"
|
|
|
|
#
|
|
# The constructor. Initializes the member variables.
|
|
#
|
|
def initialize()
|
|
super
|
|
# initialize member variables
|
|
@_buffer = TQt::Pixmap.new()
|
|
@_last = TQt::Point.new()
|
|
@_currentcolor = black
|
|
|
|
# don't blank the window before repainting
|
|
setBackgroundMode( NoBackground )
|
|
|
|
# create a pop-up menu
|
|
@_popupmenu = TQt::PopupMenu.new()
|
|
@_popupmenu.insertItem( "&Clear", self, SLOT( "slotClearArea()" ) )
|
|
end
|
|
|
|
#
|
|
# This slot sets the curren color for the scribble area. It will be
|
|
# connected with the colorChanged( TQt::Color ) signal from the
|
|
# ScribbleWindow.
|
|
#
|
|
def setColor( new_color )
|
|
@_currentcolor = new_color
|
|
end
|
|
|
|
#
|
|
# This slot clears the drawing area by filling the off-screen buffer with
|
|
# white and copying it over to the window.
|
|
#
|
|
def slotClearArea()
|
|
# fill the off screen buffer with plain white
|
|
@_buffer.fill( white )
|
|
|
|
# and copy it over to the window
|
|
bitBlt( self, 0, 0, @_buffer )
|
|
end
|
|
|
|
|
|
#
|
|
# This method does the actual loading. It relies on TQt::Pixmap (and the
|
|
# underlying I/O machinery) to determine the filetype.
|
|
#
|
|
def slotLoad( filename )
|
|
if !@_buffer.load( filename )
|
|
TQt::MessageBox.warning( nil, "Load error", "Could not load file" )
|
|
end
|
|
|
|
repaint() # refresh the window
|
|
end
|
|
|
|
|
|
#
|
|
# This method does the actual saving. We hard-code the file type as
|
|
# BMP. Unix users might want to replace this with something like XPM.
|
|
#
|
|
def slotSave( filename )
|
|
if !@_buffer.save( filename, "BMP" )
|
|
TQt::MessageBox.warning( nil, "Save error", "Could not save file" )
|
|
end
|
|
end
|
|
|
|
|
|
#
|
|
# This method is called whenever the user presses the
|
|
# mouse over the window. It just records the position of the mouse
|
|
# at the time of the click.
|
|
#
|
|
def mousePressEvent(event)
|
|
if event.button() == RightButton
|
|
@_popupmenu.exec( TQt::Cursor.pos() )
|
|
else
|
|
@_last = event.pos() # retrieve the coordinates from the event
|
|
end
|
|
end
|
|
|
|
|
|
#
|
|
# The method is called whenever the usr moves the mouse
|
|
# while the mouse button is pressed. If we had called
|
|
# setMouseTracking(true) before, the method would also be called
|
|
# when the mouse was moved with any button pressed. We know that
|
|
# we haven't, and thus don't have to check whether any buttons are
|
|
# pressed.
|
|
#
|
|
def mouseMoveEvent(event)
|
|
# create a TQt::Painter object for drawing onto the window
|
|
windowpainter = TQt::Painter.new()
|
|
# and another TQt::Painter object for drawing int an off-screen pixmap
|
|
bufferpainter = TQt::Painter.new()
|
|
|
|
# start painting
|
|
windowpainter.begin( self ) # This painter paints onto the window
|
|
bufferpainter.begin( @_buffer ) # and this one paints in the buffer
|
|
|
|
# set a standard pen with the currently selected color
|
|
windowpainter.setPen( @_currentcolor )
|
|
bufferpainter.setPen( @_currentcolor )
|
|
|
|
# draw a line in both the window and the buffer
|
|
windowpainter.drawLine( @_last, event.pos() )
|
|
bufferpainter.drawLine( @_last, event.pos() )
|
|
|
|
# done with painting
|
|
windowpainter.end()
|
|
bufferpainter.end()
|
|
|
|
# remember the current mouse position
|
|
@_last = event.pos()
|
|
end
|
|
|
|
#
|
|
# This method is called whenever the widget needs
|
|
# painting, for example when it has been obscured and then revealed again.
|
|
#
|
|
def paintEvent(event)
|
|
bitBlt(self, 0, 0, @_buffer)
|
|
end
|
|
|
|
#
|
|
# This method get called whenever the widget needs
|
|
# painting, for example, when it has been obscured and then revealed again.
|
|
#
|
|
def resizeEvent(event)
|
|
save = TQt::Pixmap.new( @_buffer )
|
|
@_buffer.resize( event.size() )
|
|
@_buffer.fill( white )
|
|
bitBlt( @_buffer, 0, 0, save )
|
|
end
|
|
end
|
|
|
|
class ScribbleWindow < TQt::Widget
|
|
|
|
slots "slotAbout()", "slotAboutQt()", "slotColorMenu(int)", "slotLoad()", "slotSave()"
|
|
signals "colorChanged(TQColor)", "load(const TQString&)", "save(const TQString&)"
|
|
|
|
COLOR_MENU_ID_BLACK = 0
|
|
COLOR_MENU_ID_RED = 1
|
|
COLOR_MENU_ID_BLUE = 2
|
|
COLOR_MENU_ID_GREEN = 3
|
|
COLOR_MENU_ID_YELLOW = 4
|
|
|
|
def initialize()
|
|
super
|
|
# The next lines build the menu bar. We first create the menus
|
|
# one by one, then add them to the menu bar. #
|
|
@_filemenu = TQt::PopupMenu.new() # create a file menu
|
|
@_filemenu.insertItem( "&Load", self, SLOT( "slotLoad()" ) )
|
|
@_filemenu.insertItem( "&Save", self, SLOT( "slotSave()" ) )
|
|
@_filemenu.insertSeparator()
|
|
@_filemenu.insertItem( "&Quit", $qApp, SLOT( "quit()" ) )
|
|
|
|
@_colormenu = TQt::PopupMenu.new() # create a color menu
|
|
@_colormenu.insertItem( "B&lack", COLOR_MENU_ID_BLACK)
|
|
@_colormenu.insertItem( "&Red", COLOR_MENU_ID_RED)
|
|
@_colormenu.insertItem( "&Blue", COLOR_MENU_ID_BLUE)
|
|
@_colormenu.insertItem( "&Green", COLOR_MENU_ID_GREEN)
|
|
@_colormenu.insertItem( "&Yellow", COLOR_MENU_ID_YELLOW)
|
|
TQt::Object.connect( @_colormenu, SIGNAL( "activated( int )" ),
|
|
self, SLOT( "slotColorMenu( int )" ) )
|
|
|
|
@_helpmenu = TQt::PopupMenu.new() # create a help menu
|
|
@_helpmenu.insertItem( "&About QtScribble", self, SLOT( "slotAbout()" ) )
|
|
@_helpmenu.insertItem( "&About Qt", self, SLOT( "slotAboutQt()" ) )
|
|
|
|
@_menubar = TQt::MenuBar.new( self, "" ) # create a menu bar
|
|
@_menubar.insertItem( "&File", @_filemenu )
|
|
@_menubar.insertItem( "&Color", @_colormenu )
|
|
@_menubar.insertItem( "&Help", @_helpmenu )
|
|
|
|
# We create a TQt::ScrollView and a ScribbleArea. The ScribbleArea will
|
|
# be managed by the scroll view.#
|
|
@_scrollview = TQt::ScrollView.new( self )
|
|
@_scrollview.setGeometry( 0, @_menubar.height(),
|
|
width(), height() - @_menubar.height() )
|
|
@_scribblearea = ScribbleArea.new()
|
|
@_scribblearea.setGeometry( 0, 0, 1000, 1000 )
|
|
@_scrollview.addChild( @_scribblearea )
|
|
TQt::Object.connect( self, SIGNAL( "colorChanged(TQColor)" ),
|
|
@_scribblearea, SLOT( "setColor(TQColor)" ) )
|
|
TQt::Object.connect( self, SIGNAL( "save(const TQString&)" ),
|
|
@_scribblearea, SLOT( "slotSave(const TQString&)" ) )
|
|
TQt::Object.connect( self, SIGNAL( "load(const TQString&)" ),
|
|
@_scribblearea, SLOT( "slotLoad(const TQString&)" ) )
|
|
end
|
|
|
|
def resizeEvent( event )
|
|
# When the whole window is resized, we have to rearrange the geometry
|
|
# in the ScribbleWindow as well. Note that the ScribbleArea does not need
|
|
# to be changed.
|
|
@_scrollview.setGeometry( 0, @_menubar.height(),
|
|
width(), height() - @_menubar.height() )
|
|
end
|
|
|
|
|
|
|
|
def slotAbout()
|
|
TQt::MessageBox.information( self, "About QtScribble 5",
|
|
"This is the Scribble 5 application\n" +
|
|
"Copyright 1998 by Mathias Kalle Dalheimer\n")
|
|
end
|
|
|
|
def slotAboutQt()
|
|
TQt::MessageBox.aboutTQt( self, "About Qt" )
|
|
end
|
|
|
|
def slotColorMenu( item )
|
|
case item
|
|
when COLOR_MENU_ID_BLACK
|
|
emit colorChanged( black )
|
|
when COLOR_MENU_ID_RED
|
|
emit colorChanged( darkRed )
|
|
when COLOR_MENU_ID_BLUE
|
|
emit colorChanged( darkBlue )
|
|
when COLOR_MENU_ID_GREEN
|
|
emit colorChanged( darkGreen )
|
|
when COLOR_MENU_ID_YELLOW
|
|
emit colorChanged( yellow )
|
|
end
|
|
end
|
|
|
|
|
|
#
|
|
# This is the slot for the menu item File/Load. It opens a
|
|
# TQt::FileDialog to ask the user for a filename, then emits a save()
|
|
# signal with the filename as parameter.
|
|
#
|
|
def slotLoad()
|
|
# Open a file dialog for loading. The default directory is the
|
|
# current directory, the filter *.bmp.
|
|
#
|
|
filename = TQt::FileDialog.getOpenFileName( ".", "*.bmp", self )
|
|
if !filename.nil?
|
|
emit load( filename )
|
|
end
|
|
end
|
|
|
|
#
|
|
# This is the slot for the menu item File/Load. It opens a
|
|
# TQt::FileDialog to ask the user for a filename, then emits a save()
|
|
# signal with the filename as parameter.
|
|
#
|
|
def slotSave()
|
|
# Open a file dialog for saving. The default directory is the
|
|
# current directory, the filter *.bmp.
|
|
#
|
|
filename = TQt::FileDialog.getSaveFileName( ".", "*.bmp", self )
|
|
if !filename.nil?
|
|
emit save( filename )
|
|
end
|
|
end
|
|
end
|
|
|
|
myapp = TQt::Application.new(ARGV)
|
|
mywidget = ScribbleWindow.new()
|
|
mywidget.setGeometry(50, 500, 400, 400)
|
|
|
|
myapp.setMainWidget(mywidget)
|
|
mywidget.show()
|
|
myapp.exec()
|