Skip to content

Commit

Permalink
Merge pull request #304 from mcorino/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
mcorino authored Sep 29, 2024
2 parents 14d0543 + c80801a commit ce59778
Show file tree
Hide file tree
Showing 9 changed files with 318 additions and 11 deletions.
14 changes: 4 additions & 10 deletions lib/wx/core/functions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,14 @@ class << self
# Allow this to be called with keyword parameters, and avoid
# segfaults on OS X with bad params
wx_about_box = self.instance_method(:about_box)
define_method(:about_box) do | info |
# If AboutDialogInfo has no version, it segfaults on OS X 10.5
no_version = ArgumentError.new("Must supply a version for AboutDialog")
define_method(:about_box) do | info, parent=nil |
case info
when Wx::AboutDialogInfo
unless info.has_version
Kernel.raise no_version
end

ab_info = info
when Hash
ab_info = Wx::AboutDialogInfo.new
ab_info.name = info[:name] || 'wxRuby application'
ab_info.version = info[:version] || Kernel.raise(no_version)
ab_info.version = info[:version] if info[:version]

ab_info.description = info[:description] || ''
ab_info.copyright = info[:copyright] || ''
Expand All @@ -36,7 +30,7 @@ class << self
ab_info.artists = info[:artists] || []
ab_info.translators = info[:translators] || []
if info.key?(:website)
ab_info.set_website(*info[:website])
ab_info.set_web_site(*info[:website])
end
if info.key?(:icon)
ab_info.icon = info[:icon]
Expand All @@ -46,7 +40,7 @@ class << self
Kernel.raise ArgumentError,
"Can't use #{info.inspect} for AboutDialogInfo"
end
wx_about_box.bind(self).call(ab_info)
wx_about_box.bind(self).call(ab_info, parent)
end
end
end
18 changes: 18 additions & 0 deletions lib/wx/doc/animation_ctrl.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# :stopdoc:
# This file is automatically generated by the WXRuby3 documentation
# generator. Do not alter this file.
# :startdoc:


module Wx

class GenericAnimationCtrl < AnimationCtrl

# This override of {Wx::AnimationCtrl#play} lets you specify if the animation must loop or not.
# @param looped [Boolean] default true
# @return [Boolean]
def play(looped = true) end

end

end
8 changes: 7 additions & 1 deletion lib/wx/keyword_defs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,13 @@
end

Wx::define_keyword_ctors(Wx::AnimationCtrl) do
wx_ctor_params :id, :anim
wx_ctor_params :id, :anim => Wx::NULL_ANIMATION
wx_ctor_params :pos, :size, :style => Wx::AC_DEFAULT_STYLE
wx_ctor_params :name => Wx::ANIMATION_CTRL_NAME_STR
end

Wx::define_keyword_ctors(Wx::GenericAnimationCtrl) do
wx_ctor_params :id, :anim => Wx::NULL_ANIMATION
wx_ctor_params :pos, :size, :style => Wx::AC_DEFAULT_STYLE
wx_ctor_params :name => Wx::ANIMATION_CTRL_NAME_STR
end
Expand Down
5 changes: 5 additions & 0 deletions rakelib/lib/director/animation_ctrl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ class AnimationCtrl < Window

def setup
super
spec.items << 'wxGenericAnimationCtrl'
spec.include 'wx/animate.h'
spec.include 'wx/generic/animate.h'
if Config.instance.wx_version >= '3.3.0'
spec.items << 'wxAnimationBundle'
spec.ignore 'wxAnimationBundle::GetAll', ignore_doc: false
Expand All @@ -38,6 +41,8 @@ def setup
map_out code: ''
end
end
spec.ignore 'wxGenericAnimationCtrl::Play'
spec.extend_interface 'wxGenericAnimationCtrl', 'bool Play(bool looped=true)'
spec.do_not_generate :variables, :enums, :defines, :functions
end
end # class AnimationCtrl
Expand Down
284 changes: 284 additions & 0 deletions samples/animate/anitest.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
# Copyright (c) 2023 M.J.N. Corino, The Netherlands
#
# This software is released under the MIT license.
#
# Adapted for wxRuby from wxWidgets widgets sample
# Copyright (c) 2001 Julian Smart

require 'wx'

module AniTest

# Define a new frame
class MyFrame < Wx::Frame

module ID
include Wx::IDHelper

PLAY = self.next_id
SET_NULL_ANIMATION = self.next_id
SET_INACTIVE_BITMAP = self.next_id
SET_NO_AUTO_RESIZE = self.next_id
SET_BGCOLOR = self.next_id
USE_GENERIC = self.next_id

end

def initialize(title)
super(nil, :title => title, :size => [500, 400], style: Wx::DEFAULT_FRAME_STYLE)

set_icon(Wx.Icon(:sample, art_path: File.dirname(__dir__)))

# Make a menubar
file_menu = Wx::Menu.new

if Wx.has_feature?(:USE_FILEDLG)
file_menu.append(Wx::ID_OPEN, "&Open Animation...\tCtrl+O", 'Loads an animation')
end # USE_FILEDLG
file_menu.append(Wx::ID_EXIT)

play_menu = Wx::Menu.new
play_menu.append(ID::PLAY, "Play\tCtrl+P", "Play the animation")
play_menu.append(Wx::ID_STOP, "Stop\tCtrl+S", "Stop the animation")
play_menu.append_separator
play_menu.append(ID::SET_NULL_ANIMATION, "Set null animation",
"Sets the empty animation in the control")
play_menu.append_check_item(ID::SET_INACTIVE_BITMAP, "Set inactive bitmap",
"Sets an inactive bitmap for the control")
play_menu.append_check_item(ID::SET_NO_AUTO_RESIZE, "Set no autoresize",
"Tells the control not to resize automatically")
play_menu.append(ID::SET_BGCOLOR, "Set background colour...",
"Sets the background colour of the control")

if Wx::PLATFORM == 'WXGTK'
play_menu.append_separator
play_menu.append_check_item(ID::USE_GENERIC, "Use &generic animation\tCtrl+G",
"Selects whether native or generic version is used")
end

help_menu = Wx::Menu.new
help_menu.append(Wx::ID_ABOUT)

menu_bar = Wx::MenuBar.new

menu_bar.append(file_menu, "&File")
menu_bar.append(play_menu, "&Animation")
menu_bar.append(help_menu, "&Help")

# Associate the menu bar with this frame
set_menu_bar(menu_bar)

if Wx.has_feature?(:USE_STATUSBAR)
create_status_bar
end # USE_STATUSBAR

# use a Wx::BoxSizer otherwise Wx::Frame will automatically
# resize the @animation_ctrl to fill its client area on
# user resizes
sz = Wx::VBoxSizer.new
sz.add(Wx::StaticText.new(self, Wx::ID_ANY, "wxAnimationCtrl:"),
Wx::SizerFlags.new.centre.border)

@animation_ctrl = Wx::AnimationCtrl.new(self, Wx::ID_ANY)

animations = Wx::AnimationBundle.new

throbber = Wx::Animation.new(File.join(__dir__, 'throbber.gif'))
animations.add(throbber) if throbber.ok?

throbber2x = Wx::Animation.new(File.join(__dir__, 'throbber_2x.gif'))
animations.add(throbber2x) if throbber2x.ok?

if animations.ok?
@animation_ctrl.set_animation(animations)
@animation_ctrl.play
end

sz.add(@animation_ctrl, Wx::SizerFlags.new.centre.border)
set_sizer(sz)

evt_menu(ID::PLAY, :on_play)
evt_menu(ID::SET_NULL_ANIMATION, :on_set_null_animation)
evt_menu(ID::SET_INACTIVE_BITMAP, :on_set_inactive_bitmap)
evt_menu(ID::SET_NO_AUTO_RESIZE, :on_set_no_auto_resize)
evt_menu(ID::SET_BGCOLOR, :on_set_bg_color)
if Wx::PLATFORM == 'WXGTK'
evt_menu(ID::USE_GENERIC, :on_use_generic)
end

evt_menu(Wx::ID_STOP, :on_stop)
evt_menu(Wx::ID_ABOUT, :on_about)
evt_menu(Wx::ID_EXIT, :on_quit)
if Wx.has_feature?(:USE_FILEDLG)
evt_menu(Wx::ID_OPEN, :on_open)
end # USE_FILEDLG

evt_size { self.layout }
evt_update_ui(Wx::ID_ANY, :on_update_ui)
end

def on_about(_event)
info = Wx::AboutDialogInfo.new
info.set_name("Wx::AnimationCtrl and Wx::Animation sample")
info.set_description("This sample program demonstrates the usage of Wx::AnimationCtrl")
info.set_copyright("(C) 2024 Martin Corino (original (C) 2006 Julian Smart)")

info.add_developer("Martin Corino")

Wx.about_box(info, self)
end

def on_quit(_event)
close
end

def on_play(_event)
Wx.log_error('Invalid animation') unless @animation_ctrl.play
end

def on_set_null_animation(_event)
@animation_ctrl.set_animation(Wx::AnimationBundle.new(Wx::NULL_ANIMATION))
end

def on_set_inactive_bitmap(event)
if event.checked?
# set a dummy bitmap as the inactive bitmap
bmp = Wx::ArtProvider.get_bitmap(Wx::ART_MISSING_IMAGE)
@animation_ctrl.set_inactive_bitmap(bmp)
else
@animation_ctrl.set_inactive_bitmap(Wx::NULL_BITMAP)
end
end

def on_set_no_auto_resize(event)
# recreate the control with the new flag if necessary
style = Wx::AC_DEFAULT_STYLE | (event.checked? ? Wx::AC_NO_AUTORESIZE : 0)

recreate_animation(style) if style != @animation_ctrl.get_window_style
end

def on_set_bg_color(_event)
clr = Wx.get_colour_from_user(self, @animation_ctrl.get_background_colour,
'Choose the background colour')

@animation_ctrl.set_background_colour(clr) if clr.ok?
end

def on_stop(_event)
@animation_ctrl.stop
end

if Wx::PLATFORM == 'WXGTK'

def on_use_generic(_event)
recreate_animation(@animation_ctrl.get_window_style)
end

end

def on_update_ui(_event)
get_menu_bar.find_item(Wx::ID_STOP).first.enable(@animation_ctrl.playing?)
get_menu_bar.find_item(ID::PLAY).first.enable(!@animation_ctrl.playing?)
get_menu_bar.find_item(ID::SET_NO_AUTO_RESIZE).first.enable(!@animation_ctrl.playing?)
end

if Wx.has_feature?(:USE_FILEDLG)

def on_open(_event)
Wx.FileDialog(self, "Please choose an animation", '', '', '*.gif;*.ani', Wx::FD_OPEN) do |dialog|
if dialog.show_modal == Wx::ID_OK
filename = dialog.get_path

temp = @animation_ctrl.create_animation
unless temp.load_file(filename)
Wx.log_error("Sorry, this animation is not a valid format for Wx::Animation.")
return
end

@animation_ctrl.set_animation(Wx::AnimationBundle.new(temp))
@animation_ctrl.play

get_sizer.layout
end
end
end

end # USE_FILEDLG

private

def recreate_animation(style)
# save status of the control before destroying it

# We can't reuse the existing animation if we're switching from native to
# generic control or vice versa (as indicated by the absence of change in
# the style, which is the only other reason we can get called). We could
# save the file name we loaded it from and recreate it, of course, but for
# now, for simplicity, just start without any animation in this case.
curr = Wx::Animation.new
if Wx::PLATFORM == 'WXGTK'
curr = @animation_ctrl.get_animation if style != @animation_ctrl.get_window_style
end

inactive = @animation_ctrl.get_inactive_bitmap
bg = @animation_ctrl.get_background_colour

# destroy & rebuild
old = @animation_ctrl

if Wx::PLATFORM == 'WXGTK' && get_menu_bar.is_checked(ID::USE_GENERIC)
@animation_ctrl = Wx::GenericAnimationCtrl.new(self, Wx::ID_ANY, curr, style: style)
else
@animation_ctrl = Wx::AnimationCtrl.new(self, Wx::ID_ANY, curr, style: style)
end

get_sizer.replace(old, @animation_ctrl)

# load old status in new control
@animation_ctrl.set_inactive_bitmap(inactive)
@animation_ctrl.set_background_colour(bg)

get_sizer.layout
end

end


class App < Wx::App

# this one is called on application startup and is a good place for the app
# initialization (doing it here and not in the ctor allows to have an error
# return: if OnInit() returns false, the application terminates)
def on_init
# Create the main frame window
frame = MyFrame.new('Animation Demo')
frame.show
end

end

end

module AniTestSample

include WxRuby::Sample if defined? WxRuby::Sample

def self.describe
{ file: __FILE__,
summary: 'wxRuby AnimationCtrl example.',
description: <<~__DESC
A Ruby port of the wxWidgets anitest sample which showcases
animation controls.
__DESC
}
end

def self.run
execute(__FILE__)
end

if $0 == __FILE__
AniTest::App.run
end

end
Binary file added samples/animate/hourglass.ani
Binary file not shown.
Binary file added samples/animate/throbber.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added samples/animate/throbber_2x.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added samples/animate/tn_anitest.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit ce59778

Please sign in to comment.