Advertisement
Iavra

[Ace] Generic Popup

Jun 7th, 2015
331
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 14.20 KB | None | 0 0
  1. #==============================================================================
  2. # Iavra Generic Popup 1.01
  3. # -----------------------------------------------------------------------------
  4. # Description:
  5. # Provides a generic way to display popup messages.
  6. # -----------------------------------------------------------------------------
  7. # Prerequisites:
  8. # None
  9. # -----------------------------------------------------------------------------
  10. # How to Use:
  11. # To show a new popup message, call the following method:
  12. #
  13. # IAVRA::POPUP.show("abc")
  14. #
  15. # The window height will automatically fit to the number of text lines.
  16. #
  17. # The method takes an optional hash, which can be used to override the default
  18. # settings on a per-window basis, like this:
  19. #
  20. # IAVRA::POPUP.show("abc", {:width => 200})
  21. #
  22. # Also, the method can take an optional block, that will be called once the
  23. # popup window is created. "self" inside the proc is set to the window itself:
  24. #
  25. # IAVRA::POPUP.show("abc") { p self }
  26. #
  27. # You can use all message codes in your text, but need to double backslashes
  28. # for everything except newlines (\n).
  29. #
  30. # The popup will fade out over time and dispose itself afterwards.
  31. #
  32. # Popups are global and will persist between scenes. Certain scenes can be set
  33. # to dispose existing popups by modifying the DISPOSE_ON_SCENE constant.
  34. # -----------------------------------------------------------------------------
  35. # Terms of Use:
  36. # Free to use for both commercial and non-commercial games. Please give credit.
  37. # -----------------------------------------------------------------------------
  38. # Credits:
  39. # Iavra
  40. # -----------------------------------------------------------------------------
  41. # Changelog:
  42. # - 1.00: Release version.
  43. # - 1.01: Changed the way popup options are handled. The show method now takes
  44. #         an optional hash, that can be used to override the global defaults
  45. #         on a per-window basis. Everything except the z-index can be modified.
  46. #==============================================================================
  47.  
  48. ($imported ||= {})[:iavra_generic_popup] = true
  49.  
  50. #==============================================================================
  51. # ▼ IAVRA::POPUP
  52. #==============================================================================
  53.  
  54. module IAVRA
  55.     module POPUP
  56.        
  57.         #==========================================================================
  58.         # ■ ■ ■ ■ ■ CONFIGURATION ■ ■ ■ ■ ■
  59.         #==========================================================================
  60.        
  61.         #==========================================================================
  62.         # Default options when creating new windows. Can be overriden on a per-
  63.         # window basis by using the "options" parameter:
  64.         #
  65.         # :width =>         Window width
  66.         # :min_lines =>     Minimum number of lines to display. Can be nil.
  67.         # :max_lines =>     Maximum number of lines to display. Can be nil.
  68.         # :line_height =>   Height of a single line. Set to nil for default.
  69.         # :padding =>       Window padding. Set to nil for default.
  70.         # :spacing =>       Spacing between windows. The update method can use this.
  71.         # :windowskin =>    Windowskin to be used. Set to nil for default.
  72.         # :fade_delay =>    Number of frames before the window starts fading.
  73.         # :fade_rate =>     Rate at which the window fades out after the delay.
  74.         # :update_method => Update method to be used.
  75.         #==========================================================================
  76.        
  77.         DEFAULT_OPTIONS = {
  78.             :width => 400,
  79.             :min_lines => nil,
  80.             :max_lines => nil,
  81.             :line_height => nil,
  82.             :padding => nil,
  83.             :spacing => 10,
  84.             :windowskin => nil,
  85.             :fade_delay => 120,
  86.             :fade_rate => 10,
  87.             :update_method => :push_older_up
  88.         }
  89.        
  90.         #==========================================================================
  91.         # Z-index of the popup viewport.
  92.         #==========================================================================
  93.  
  94.         Z_INDEX = 1
  95.        
  96.         #==========================================================================
  97.         # When a scene listed in here becomes active, all popups will be disposed.
  98.         # Add Scene_Base to dispose all popups whenever a scene changes.
  99.         #==========================================================================
  100.        
  101.         DISPOSE_ON_SCENE = [
  102.             Scene_Title, Scene_Gameover, Scene_File
  103.         ]
  104.        
  105.         #==========================================================================
  106.         # ■ ■ ■ ■ ■ CONFIGURATION ■ ■ ■ ■ ■
  107.         #==========================================================================
  108.        
  109.         #==========================================================================
  110.         # A number of predefined update methods, accessible by symbol. You can add
  111.         # new ones if you know what to do. The update method takes 2 parameters:
  112.         # - The list of all currently displayed windows.
  113.         # - The index of the window, which is updated.
  114.         #
  115.         # Also, "self" inside the proc is set to the window itself.
  116.         #==========================================================================
  117.        
  118.         UPDATE_PROCS = {
  119.            
  120.             # This can be used in combination with the callback proc to animate the
  121.             # popups by other means, like "Iavra Animate Everything".
  122.            
  123.             :none => lambda {|list, index|},
  124.            
  125.             # This method displays popups in the lower left corner and adds new ones
  126.             # on top. Once an older popup fades out, the remaining ones move down.
  127.            
  128.             :add_on_top => lambda {|list, index|
  129.                 self.y = Graphics.height - list.map.with_index{|w, i|
  130.                     (i <= index) && !w.disposed? ? (w.height + w.spacing) : 0
  131.                 }.reduce(:+)
  132.             },
  133.            
  134.             # This method displays popups in the lower left corner and adds new ones
  135.             # to the bottom, pushing older ones upward.
  136.            
  137.             :push_older_up => lambda {|list, index|
  138.                 self.y = Graphics.height - list.map.with_index{|w, i|
  139.                     (i >= index) && !w.disposed? ? (w.height + w.spacing) : 0
  140.                 }.reduce(:+)
  141.             }
  142.            
  143.             # Be free to add your own methods here.
  144.         }
  145.        
  146.         #==========================================================================
  147.         # All popups are displayed in their own viewport. The viewport never gets
  148.         # disposed, but since it's used throughout the whole game, this shouldn't
  149.         # be too much of a problem.
  150.         #==========================================================================
  151.        
  152.         VIEWPORT = Viewport.new
  153.         VIEWPORT.z = Z_INDEX
  154.        
  155.         #==========================================================================
  156.         # For storing the active popups.
  157.         #==========================================================================
  158.        
  159.         @popups = []
  160.        
  161.         #==========================================================================
  162.         # Adds a new popup window with the given text. Message codes can be used.
  163.         #
  164.         # An optional hash be can given to overwrite some of the default options.
  165.         #
  166.         # Can be called with an optional block that will be called, once the popup
  167.         # is created.
  168.         #==========================================================================
  169.            
  170.         def self.show(text, options = {}, &callback)
  171.             @popups << Window_Popup.new(text, options, &callback)
  172.         end
  173.        
  174.         #==========================================================================
  175.         # Called every frame by Scene_Base to update popup position and opacity.
  176.         #==========================================================================
  177.        
  178.         def self.update
  179.             @popups.each {|popup| popup.update}
  180.         end
  181.        
  182.         #==========================================================================
  183.         # Called on scene exit to dispose all popups an clear the list.
  184.         #==========================================================================
  185.        
  186.         def self.cleanup
  187.             return unless DISPOSE_ON_SCENE.map{|scene| SceneManager.scene.is_a?(scene)}.any?
  188.             @popups.each {|popup| popup.dispose}
  189.             @popups.clear
  190.         end
  191.        
  192.         #==========================================================================
  193.         # Toggles visibility on or off for all popups.
  194.         #==========================================================================
  195.        
  196.         def self.hide_all
  197.             @popups.each {|popup| popup.visible = false}
  198.         end
  199.        
  200.         def self.show_all
  201.             @popups.each {|popup| popup.visible = true}
  202.         end
  203.        
  204.         #==========================================================================
  205.         # Returns the list of all currently displayed popups.
  206.         #==========================================================================
  207.        
  208.         def self.list
  209.             @popups
  210.         end
  211.        
  212.         #==========================================================================
  213.         # ▼ IAVRA::POPUP::Window_Popup
  214.         # -------------------------------------------------------------------------
  215.         # The popup window class. Namespaced to prevent possible conflicts with
  216.         # other popup scripts.
  217.         #==========================================================================
  218.        
  219.         class Window_Popup < ::Window_Base
  220.            
  221.             attr_reader :spacing
  222.            
  223.             #========================================================================
  224.             # Initializes a new popup window. First merges the default options with
  225.             # the given overrides (if any) and then initializes the window:
  226.             #
  227.             # - Set line_height, padding, spacing, fade delay and fade rate according
  228.             #   to the options.
  229.             #
  230.             # - Calculates the number of text lines needed by using a dummy window.
  231.             #   Then caps that value at the lower and upper bounds, if any.
  232.             #
  233.             # - Initializes the window, sets the viewport and windowskin. The window
  234.             #   is created outside the visible part of the screen, since the update
  235.             #   method will define it's position during the first update.
  236.             #
  237.             # - Draws the text (again).
  238.             #
  239.             # - Defines the given update method on the singleton class.
  240.             #
  241.             # - Executes the given callback proc, if any.
  242.             #========================================================================
  243.            
  244.             def initialize(text, options = {}, &callback)
  245.                 o = DEFAULT_OPTIONS.merge(options)
  246.                
  247.                 # window settings
  248.                 @line_height, @padding, @spacing, @fade_delay, @fade_rate =
  249.                 o.values_at(:line_height, :padding, :spacing, :fade_delay, :fade_rate)
  250.                
  251.                 # calculate height
  252.                 dummy = Window_Dummy.new(text)
  253.                 lines = dummy.iavra_popup_num_lines
  254.                 dummy.dispose
  255.                 lines = [(min = o[:min_lines] || lines), (o[:max_lines] || min), lines].sort[1]
  256.                 height = fitting_height(lines)
  257.                
  258.                 # initialize
  259.                 super(0, -height, o[:width], height)
  260.                 self.viewport = VIEWPORT
  261.                 self.windowskin = Cache.system(o[:windowskin]) if o[:windowskin]
  262.                
  263.                 # draw text
  264.                 draw_text_ex(0, 0, text)
  265.                
  266.                 # set update method
  267.                 define_singleton_method(:update_position, UPDATE_PROCS[o[:update_method]])
  268.                
  269.                 # execute callback, if any
  270.                 instance_eval &callback if block_given?
  271.             end
  272.            
  273.             #========================================================================
  274.             # Line height
  275.             #========================================================================
  276.            
  277.             def line_height
  278.                 @line_height || super
  279.             end
  280.            
  281.             #========================================================================
  282.             # Padding
  283.             #========================================================================
  284.            
  285.             def standard_padding
  286.                 @padding || super
  287.             end
  288.            
  289.             #========================================================================
  290.             # Updates the position and opacity of the window
  291.             #========================================================================
  292.            
  293.             def update
  294.                 super
  295.                 list = IAVRA::POPUP.list
  296.                 update_position(list, list.index(self))
  297.                 update_opacity
  298.             end
  299.  
  300.             #========================================================================
  301.             # Updates the opacity. Once it hits 0, the window is disposed and removes
  302.             # itself from the list.
  303.             #========================================================================
  304.            
  305.             def update_opacity
  306.                 if((@fade_delay -= 1) <= 0)
  307.                     self.opacity -= @fade_rate
  308.                     self.contents_opacity -= @fade_rate
  309.                 end
  310.                 if(self.opacity == 0)
  311.                     dispose
  312.                     IAVRA::POPUP.list.delete(self)
  313.                 end
  314.             end
  315.            
  316.         end
  317.        
  318.         #==========================================================================
  319.         # ▼ IAVRA::POPUP::Window_Dummy
  320.         # -------------------------------------------------------------------------
  321.         # A dummy window used to calculate the number of lines needed.
  322.         #==========================================================================
  323.        
  324.         class Window_Dummy < ::Window_Base
  325.            
  326.             attr_reader :iavra_popup_num_lines
  327.            
  328.             def initialize(text)
  329.                 super(0, 0, 0, 0)
  330.                 @iavra_popup_num_lines = 1
  331.                 draw_text_ex(0, 0, text)
  332.             end
  333.            
  334.             def process_new_line(text, pos)
  335.                 super(text, pos)
  336.                 @iavra_popup_num_lines += 1
  337.             end
  338.            
  339.         end
  340.            
  341.     end
  342. end
  343.  
  344. #==============================================================================
  345. # ▼ Scene_Base
  346. #==============================================================================
  347.  
  348. class Scene_Base
  349.  
  350.     alias :iavra_popup_update_all_windows :update_all_windows
  351.     alias :iavra_popup_dispose_all_windows :dispose_all_windows
  352.    
  353.     #============================================================================
  354.     # Updates all popup windows.
  355.     #============================================================================
  356.    
  357.     def update_all_windows(*args)
  358.         iavra_popup_update_all_windows(*args)
  359.         IAVRA::POPUP.update
  360.     end
  361.    
  362.     #============================================================================
  363.     # Cleanup on scene end.
  364.     #============================================================================
  365.    
  366.     def dispose_all_windows(*args)
  367.         IAVRA::POPUP.cleanup
  368.         iavra_popup_dispose_all_windows(*args)
  369.     end
  370.  
  371. end
  372.  
  373. #==============================================================================
  374. # ▼ SceneManager
  375. #==============================================================================
  376.  
  377. module SceneManager
  378.    
  379.     class << self
  380.         alias :iavra_popup_snapshot_for_background :snapshot_for_background
  381.     end
  382.    
  383.     #============================================================================
  384.     # Hide all popups before creating the background image, so they don't appear
  385.     # on it.
  386.     #============================================================================
  387.    
  388.     def self.snapshot_for_background
  389.         IAVRA::POPUP.hide_all
  390.         iavra_popup_snapshot_for_background
  391.         IAVRA::POPUP.show_all
  392.     end
  393.    
  394. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement