坑爹物无误,没有优化,BUG一坨。
$apicache = {} class String def apicall(*args) $apicache[self] = Win32API.new(*self.split("|")) unless $apicache.include? self $apicache[self].call(*args) end end class Symbol def method_missing(*args, &block) self.to_s.send(*args, &block) end end class Win32API WM_ACTIVATEAPP=0x1C WM_MOUSEMOVE=0x200 WM_MOUSEWHEEL = 0x020A WM_LBUTTONDOWN = 0x201 WM_RBUTTONDOWN = 0x204 WM_MOUSEDOWN = 0x210 WM_LBUTTONUP = 0x202 WM_RBUTTONUP = 0x205 WM_LBUTTONDBLCLK = 0x203 WM_RBUTTONDBLCLK = 0x204 end module Roost module MainWindow def self.getwndproc @wndproc end def self.setwndproc(obj) @wndproc=obj end def self.addwndproc(obj) @@wndprocs.push(obj) end @@wndprocs=[] @wndproc = lambda {|hwnd, msg, wp, lp| @@handle=false for i in @@wndprocs i.call(hwnd, msg, wp, lp) end return Roost::MainWindow.use_rm_proc(hwnd, msg, wp, lp) } def self.use_rm_proc(hwnd,msg,wp,lp) if (not @@handle) @@handle=true return :"user32|CallWindowProc|iiiii|i".apicall(@@oHandle,hwnd,msg,wp,lp) end end def self.disable_rm_proc @@handle=true end def self.enable Roost::MainWindow.instance_eval do def self.enable end end Roost::MainWindow.instance_eval do @msg = "\0"*24 @hwnd = 0 while @hwnd==0 :"user32|GetMessage|piii|v".apicall(@msg, 0, 0, 0) @kmsg = @msg :"user32|TranslateMessage|p|v".apicall(@kmsg) :"user32|DispatchMessage|p|v".apicall(@kmsg) @hwnd = @msg.unpack("i*")[0] end @hdc = :"user32|GetDC|i|i".apicall(@hwnd) def self.hwnd return @hwnd end def self.hdc return @hdc end def self.findProc(l, n) lib = :"kernel32|LoadLibrary|p|i".apicall(l); ret = :"kernel32|GetProcAddress|ip|l".apicall(lib, n); :"kernel32|FreeLibrary|l|v".apicall(lib) return ret end def self.loadfindProc(l, n) lib = :"kernel32|LoadLibrary|p|i".apicall(l); ret = :"kernel32|GetProcAddress|ip|l".apicall(lib, n); return ret end def self.enableWndProc Roost::MainWindow.instance_eval do def self.enableWndProc end end @malloc = :"msvcrt|malloc|i|i" @memcpy = :"msvcrt|memcpy|ipi|v" sprintf = self.findProc("msvcrt", "sprintf") rgsseval = self.findProc("RGSS300", "RGSSGetInt") old = :"user32|GetWindowLong|ll|l".apicall(@hwnd, -4) buf = @malloc.apicall(1024) fmt = @malloc.apicall(2048) sprintfvar = @malloc.apicall(8) rgssevalvar= @malloc.apicall(8) oldvar = @malloc.apicall(8) fmtvar = @malloc.apicall(8) bufvar = @malloc.apicall(8) defvar = @malloc.apicall(8) :"msvcrt|strcpy|pp|p".apicall(fmt, "Roost::MainWindow.getwndproc.call(%d,%d,%d,%d)") @memcpy.apicall(sprintfvar, [sprintf].pack("i"), 4) @memcpy.apicall(rgssevalvar,[rgsseval].pack("i"), 4) @memcpy.apicall(oldvar, [old].pack("i"), 4) @memcpy.apicall(fmtvar, [fmt].pack("i"), 4) @memcpy.apicall(bufvar, [buf].pack("i"), 4) @memcpy.apicall(defvar, [self.findProc("user32", "DefWindowProcA")].pack("i"), 4) @code = [0x55,0x89,0xe5,0xff,0x75,0x14, 0xff,0x75,0x10,0xff,0x75,0x0c, 0xff,0x75,0x08,0xff,0x35].pack('C*') @code << [fmtvar].pack('l') << [0xff, 0x35].pack('C*') @code << [bufvar].pack('l') << [0xff, 0x15].pack('C*') @code << [sprintfvar].pack("l") @code << [0xff, 0x15].pack('C*') @code << [rgssevalvar].pack("l") =begin @code << [0x83,0xc4,0x18, 0xff, 0x75, 0x14, 0xff,0x75, 0x10, 0xff, 0x75, 0x0c, 0xff,0x75, 0x08, 0xff, 0x15].pack('C*') @code << [oldvar].pack("l") =end @code << [0x83,0xc4,0x18].pack('C*') @code << [0xc9,0xc2,0x10,0x00].pack('C*') #0xD1, 0xE8 @shellcode = @malloc.apicall(2048) @memcpy.apicall(@shellcode, @code, @code.size) @@oHandle= :"user32|SetWindowLong|iii|i".apicall(@hwnd, -4, @shellcode) #Returning Test : should be 5 #Roost::MainWindow.setwndproc (lambda{|hwnd, msg, wp, lp| 5}) #p :"user32|CallWindowProc|iiiii|i".apicall(@shellcode, 0, 0, 0, 0) end end end end end Roost::MainWindow.enable Roost::MainWindow.enableWndProc module Mouse module_function LKEY,RKEY,MKEY = 1,2,4 DBLCTIME = (Win32API.new('user32','GetDoubleClickTime','','l').call * 60.0 / 1000).round @count = 0 ## 双击时间计数 @dblc = [] ## 双击记录[key,wait,[mouse_x,mouse_y]] @move_pos = [] ## 移动记录 @clicks = [] ## 单击记录 def _init_ @press,@toggled=0,0 @pos=[0,0] Roost::MainWindow.addwndproc (lambda {|hwnd, msg, wp, lp| Mouse.onLMouseDown if msg==Win32API::WM_LBUTTONDOWN Mouse.onRMouseDown if msg==Win32API::WM_RBUTTONDOWN Mouse.onLMouseUp if msg==Win32API::WM_LBUTTONUP Mouse.onRMouseUp if msg==Win32API::WM_RBUTTONUP Mouse.onLMouseDD if msg==Win32API::WM_LBUTTONDBLCLK Mouse.onRMouseDD if msg==Win32API::WM_RBUTTONDBLCLK if msg==Win32API::WM_MOUSEMOVE Mouse.setMouse([lp&0xffff,lp>>16]) end if msg==Win32API::WM_LBUTTONDOWN or msg==Win32API::WM_RBUTTONDOWN UIManager.onMouseDown end if msg==Win32API::WM_LBUTTONUP or msg==Win32API::WM_RBUTTONUP UIManager.onMouseUp end if msg==Win32API::WM_MOUSEMOVE UIManager.onMouseMove end }) @ldown=false @ltd=false @rdown=false @rtd=false @lup=false @rup=false end def onLMouseDown @ltd=true @ltd=false if @ldown @ldown=true #UIManager.onLMouseDown end def onLMouseUp @ldown=false @ltd=false #UIManager.onLMouseUp end def onLMouseDD end def onRMouseDown @rtd=true @rtd=false if @rdown @rdown=true #UIManager.onRMouseDown end def onRMouseUp @rdown=false @rtd=false #UIManager.onRMouseUp end def onRMouseDD end def setMouse(p) @pos=p end #-------------------------------------------------------------------------- # ## 触发? #-------------------------------------------------------------------------- def self.toggled?(key) return @toggled & key != 0 end #-------------------------------------------------------------------------- # ## 按下? #-------------------------------------------------------------------------- def Mouse.press?(key) return @press & key != 0 end #-------------------------------------------------------------------------- # ## 单击? #-------------------------------------------------------------------------- def self.click?(key) return false if key == LKEY and !$click_abled return @clicks[0] & key == 0 && @clicks[1] & key != 0 end #-------------------------------------------------------------------------- # ## 双击? #-------------------------------------------------------------------------- def self.dbl_click?(key) return false if @dblc.size < 2 ## 键值有效 if @dblc[1][0] & key != 0 and @dblc[0][0] & key != 0 ## 间隔有效 if @dblc[1][1] - @dblc[0][1] < DBLCTIME ## 坐标有效 if @dblc[1][2] == @dblc[0][2] return @clicks[0] & key == 0 && @clicks[1] & key != 0 end end end return false end def pos return @pos end def update @press,@toggled=0,0 @press += LKEY if @ldown @press += RKEY if @rdown @toggled += LKEY if @ltd @toggled += RKEY if @rtd @clicks.shift if @clicks.size >=2 @clicks.push @press if @dblc.size >= 2 @dblc.clear @count = 0 end if @dblc.size == 1 and @count - @dblc[0][1] > DBLCTIME @dblc.clear @count = 0 end if @clicks[0] == 0 and @clicks[1] != 0 if @dblc.size == 1 and @dblc[0][0] != @clicks[1] @dblc.clear @count = 0 end @dblc.push [@press,@count,@pos] end @count += 1 unless @dblc.empty? @move_pos.shift if @move_pos.size >= 2 @move_pos.push @pos $click_abled=true end def down(p) if (p==LEFT) return @ldown else return @rdown end end end Roost::MainWindow.addwndproc (lambda {|hwnd, msg, wp, lp| if (msg==Win32API::WM_ACTIVATEAPP) Roost::MainWindow.disable_rm_proc return 0 end }) Mouse._init_ class << Mouse Win32API.new('user32', 'ShowCursor', 'l', 'l').call(0) $mousec = Sprite.new $mousec.z = 10001 $mousec.x = $mousec.y = 1000 $mouse_icon = 'Pointer' $mousec.bitmap = Cache.system($mouse_icon) alias wor_mouse_upd_mouse update unless $@ def Mouse.update wor_mouse_upd_mouse if $mouse_old_icon.nil? or $mouse_old_icon != $mouse_icon $mouse_old_icon = $mouse_icon $mousec.bitmap = Cache.system($mouse_old_icon) end if @pos.nil? $mousec.x = 1000 if $mousec.x != 1000 $mousec.y = 1000 if $mousec.y != 1000 Win32API.new('user32', 'ShowCursor', 'l', 'l').call(1) else $mousec.x = @pos[0] if $mousec.x != @pos[0] $mousec.y = @pos[1] if $mousec.y != @pos[1] Win32API.new('user32', 'ShowCursor', 'l', 'l').call(0) end ## 鼠标刷新 $mousec.update end #-------------------------------------------------------------------------- # ## 经过? # obj : 对象实例 # **支持Sprite,Window,Viewport,Rect,Plane,可补充 #-------------------------------------------------------------------------- def Mouse.over?(obj) case obj when Sprite x = obj.x-obj.ox; y = obj.y-obj.oy unless obj.viewport.nil? x += obj.viewport.rect.x y += obj.viewport.rect.y end return Mouse.area?(x, y, obj.width, obj.height) when Window x = obj.x;y = obj.y unless obj.viewport.nil? x += obj.viewport.rect.x y += obj.viewport.rect.y end return Mouse.area?(x, y, obj.width, obj.height) when Viewport return Mouse.area?(obj.rect.x, obj.rect.y, obj.rect.width, obj.rect.height) when Rect return Mouse.area?(obj.x, obj.y, obj.width, obj.height) when Plane x = obj.x;y = obj.y unless obj.viewport.nil? x += obj.viewport.rect.x y += obj.viewport.rect.y end return Mouse.area?(x, y, obj.width, obj.height) end end #-------------------------------------------------------------------------- # * Mouse in_area #-------------------------------------------------------------------------- def Mouse.area?(x, y, width=32, height=32) return false if @pos == nil return true if @pos[0] >= x and @pos[0] <= (x+width) and @pos[1] >= y and @pos[1] <= (y+height) return false end end #============================================================================== # ## Window_Selectable #============================================================================== class Window_Selectable < Window_Base alias wor_winsel_ini_mouse initialize alias wor_winsel_upd_mouse update def initialize(*args) wor_winsel_ini_mouse(*args) @scroll_wait = 0 @cursor_wait = 0 end def update wor_winsel_upd_mouse if self.active and self.visible update_mouse end end def update_mouse @cursor_wait -= 1 if @cursor_wait > 0 (0...item_max).each do |i| irect = mouse_rect(i) irx = self.x + 16 + irect.x - self.ox iry = self.y + 16 + irect.y - self.oy result = Mouse.area?(irx, iry, irect.width, irect.height) move_cursor(i) if result ## 控制单击条件 $click_abled = false if i == @index and !result end end ## 鼠标区域 def mouse_rect(i) rect = item_rect(i) return rect if rect.width <= 32 rect.x += 4 rect.y += 4 rect.width -= 8 rect.height -= 8 return rect end def column_max return row_max end def move_cursor(index) ## 不响应 return if @cursor_wait > 0 return if self.index == index @scroll_wait -= 1 if @scroll_wait > 0 row1 = self.index / column_max row2 = index / column_max bottom = self.top_row + (self.page_row_max - 1) if row1 == self.top_row and row2 < self.top_row return if @scroll_wait > 0 self.index = [self.index - column_max, 0].max @scroll_wait = 4 elsif row1 == bottom and row2 > bottom return if @scroll_wait > 0 self.index = [self.index + column_max, item_max - 1].min @scroll_wait = 4 else self.index = index end return if @cursor_wait > 0 Sound.play_cursor @cursor_wait += 2 end end class Rect
def inarea?(pos) xok = pos[0].between?((self.x),self.width+self.x) yok = pos[1].between?((self.y),self.height+self.y) return ((xok) and (yok)) end end module UIManager module_function def _init_ @@windowlist=[] @@topwindowlist=[] @@vireport=Viewport.new @@vireport.z=9990 @@active=nil @@draging=false @@mousepos=[0,0] @jumpflag=0 @handlemouse=false @@windowSprite=Sprite.new(@@vireport) @@windowSprite.bitmap=Bitmap.new(Graphics.width,Graphics.height) @redraw=true end def viewport return @@vireport end def onMouseDown @hlist=@@windowlist+@@topwindowlist for z in 0...@hlist.size i=@hlist[@hlist.size-z-1] if i.rect.inarea?(Mouse.pos) i.startEvent(YUI::Events::OnMouseDown,Mouse,YUI::EventMessage.new({})) return end end end def onMouseUp @hlist=@@windowlist+@@topwindowlist for z in 0...@hlist.size i=@hlist[@hlist.size-z-1] if i.rect.inarea?(Mouse.pos) i.startEvent(YUI::Events::OnMouseUp,Mouse,YUI::EventMessage.new({}) ) return end end end def onMouseMove @hlist=@@windowlist+@@topwindowlist @hked=false for z in 0...@hlist.size i=@hlist[@hlist.size-z-1] if i.rect.inarea?(Mouse.pos) i.startEvent(YUI::Events::OnMouseMove,Mouse,YUI::EventMessage.new({}) ) return end end end def _update_ rst = YUI::EventResult.new {} @z=100 @click=false Mouse.update @click = true if Mouse.click?(Mouse::LKEY) @tlist=[] @mouseskip=false @hlist=@@windowlist+@@topwindowlist @redraw=false for z in 0...@hlist.size i=@hlist[@hlist.size-z-1] if (not @mouseskip) or @@dragobj==i if (i.rect.inarea?(Mouse.pos))and (@click) @handlemouse=true if (@@active!=i) @@active.startEvent(YUI::Events::OnLoseActive,self,nil) if @@active!=nil @@active=i @@oldactive=i msg=YUI::EventMessage.new({}) i.startEvent(YUI::Events::OnActive,self,msg) if @@windowlist.include?(i) @@windowlist.delete(i) @@windowlist<<i end i.need_render=true @redraw=true end dragRect=Rect.new(i.rect.x+i.childrect.x,i.rect.y+i.childrect.y,i.childrect.width,i.childrect.height) unless (dragRect.inarea?(Mouse.pos)) @@draging=true @@dragobj=i @@mousepos=Mouse.pos @jumpflag=0 end end if ((Mouse.press?(Mouse::LKEY) or @jumpflag<0) and @@draging) @jumpflag+=1 unless Mouse.press?(Mouse::LKEY) @jumpflag=0 if Mouse.press?(Mouse::LKEY) @handlemouse=true if (i.rect.inarea?(Mouse.pos)) dragRect=Rect.new(i.rect.x+i.childrect.x,i.rect.y+i.childrect.y,i.childrect.width,i.childrect.height) unless (dragRect.inarea?(Mouse.pos)) i.rect.x+=Mouse.pos[0]-@@mousepos[0] i.rect.y+=Mouse.pos[1]-@@mousepos[1] @redraw=true @@mousepos=Mouse.pos @jumpflag=0 end end else @redraw=true if @@draging @@draging=false @@dragobj=nil @@mousepos=[0,0] end if i.rect.inarea?(Mouse.pos) @mouseskip=true end end i.sprite.x=i.rect.x i.sprite.y=i.rect.y @redraw=true if (i.sprite.x!=i.rect.x) or (i.sprite.y!=i.rect.y) if i.need_render @redraw=true if i.sprite.bitmap.nil? or (i.sprite.bitmap.width!=i.rect.width) or(i.sprite.bitmap.height!=i.rect.height) i.sprite.bitmap.dispose unless i.sprite.bitmap.nil? or i.sprite.bitmap.disposed? bit = Bitmap.new(i.rect.width,i.rect.height) else bit=i.sprite.bitmap bit.clear end frameUpdate = YUI::EventMessage.new ({:result => rst,:bitmap => bit} ) i.sprite.bitmap=bit i.startEvent(YUI::Events::OnRender,self,frameUpdate) i.bak_bitmap=i.sprite.bitmap.clone i.need_render=false end i.sprite.z=@hlist.size-z-1 end if $摸你傻效果开关,慎用! if @redraw @@windowSprite.bitmap.clear#dispose #@@windowSprite.bitmap=Graphics.snap_to_bitmap #.clear for z in 0...@hlist.size i=@hlist[z] if not @@draging bitmap=Bitmap.new(i.rect.width,i.rect.height) bitmap.blt(0,0,@@windowSprite.bitmap,Rect.new(i.rect.x,i.rect.y,i.rect.width,i.rect.height)) #bitmap.radial_blur(120,16)#blur 2.times {bitmap.blur} @@windowSprite.bitmap.clear_rect(Rect.new(i.rect.x,i.rect.y,i.rect.width,i.rect.height)) @@windowSprite.bitmap.blt(i.rect.x,i.rect.y,bitmap,Rect.new(0,0,i.rect.width,i.rect.height)) end @@windowSprite.bitmap.blt(i.rect.x,i.rect.y,i.sprite.bitmap,Rect.new(0,0,i.rect.width,i.rect.height)) end #@@windowSprite.bitmap.blur if not @@draging end end end def createWindow(window,*args) return @@windowlist<<window.new(window,*args)# if window.is_a?(YUI::Window) return false end def change_theme for i in @@windowlist+@@topwindowlist i.setThemeData i.need_render=true end end def disposeWindow(window) result=YUI::EventResult.new{|o|o.cancel=false} window.startEvent(YUI::Events::OnDispose,self,YUI::EventMessage.new({:result=>result}) ) unless result.cancel @@windowlist.delete(window) @@topwindowlist.delete(window) window.sprite.bitmap.dispose window.sprite.dispose end end def handlemouse? return @handlemouse end end UIManager._init_ #Innerface To Update class <<Graphics # if @@old_update_UIManager.nil? #p methods alias old_update update def update UIManager._update_ old_update end # end endmodule YUI
class Theme @@list={ :WindowNCBackGroundColor=>[Color.new(0,0,0,120),Color.new(255,255,255,120),false], :WindowBackGroundColor=>Color.new(255,255,255,220), :CT=>32, :CL=>1, :CR=>1, :CB=>1, :titleFont=>Font.new("微软雅黑",24), :WindowContentOpcity=>120 } @@functions={} # @@list[:titleFont].shadow=true # @@list[:titleFont].bold = true @@list[:titleFont].color=Color.new(255,255,255) def [](k) if not @@args[1].theme.nil? if not @@args[1].theme[k].nil? return @@args[1].theme[k] end end return @@list[k] end def regfunc(name,proc) @@functions[name]=proc end def setdata(sender,*args) @@args=[nil,sender,args] end def func(name,sender,*args) @@args=[name,sender,args] if not sender.theme[name].nil? sender.theme[name].call(name,sender,*args) return end if args.size>0 case name when :WindowNCBackGround args[0].gradient_fill_rect(0,0,args[0].width,args[0].height,self[:WindowNCBackGroundColor][0],self[:WindowNCBackGroundColor][1],self[:WindowNCBackGroundColor][2]) if args[2][1]==:Normally args[0].font = self[:titleFont] else args[0].font = args[2][1] end args[0].draw_text(5,5,args[0].width-10,24,args[2][0]) #args[0].blur when :WindowBackGround args[0].clear_rect(self[:CL],self[:CT],args[0].width-self[:CL]-self[:CR],args[0].height-self[:CT]-self[:CB]) args[0].fill_rect(self[:CL],self[:CT],args[0].width-self[:CL]-self[:CR],args[0].height-self[:CT]-self[:CB],self[:WindowBackGroundColor]) else unless @@functions[name].nil? @@functions[name].call(name,*args) else raise "not defined theme" end end end end end module Themes module_function @@reg={} def _init_ @theme=Theme.new end def regnewfunc(name,&proc) @@reg[name]=proc @theme.regfunc(name,proc) end def _load(filename,classname) require filename @theme = eval(classname+".new") for i in @@reg.keys @theme.regfunc(i,@@reg[i]) end UIManager.change_theme end def _load_by_monery_(data,classname) eval(data) @theme = eval(classname+".new") for i in @@reg.keys @theme.regfunc(i,@@reg[i]) end UIManager.change_theme end def get(name,sender,*args) @theme.setdata(sender,*args) return @theme[name] end def draw(func,sender,*args) @theme.func(func,sender,*args) end end end YUI::Themes._init_module YUI
module Events @@count=1 Ents={} def self.yui_getfreeid return @@count end def self.yui_addfreeid @@count+=1 end def self.yui_getaddfreeid(name) yui_addfreeid Ents[yui_getfreeid-1]=name return yui_getfreeid-1 end OnCreate=yui_getaddfreeid :OnCreate OnDispose=yui_getaddfreeid :OnDispose OnMouseMove=yui_getaddfreeid :OnMouseMove OnMouseDown=yui_getaddfreeid :OnMouseDown OnMouseUp=yui_getaddfreeid :OnMouseUp OnMouseOver=yui_getaddfreeid :OnMouseOver OnMouseLeave=yui_getaddfreeid :OnMouseLeave OnKeyBoardDown=yui_getaddfreeid :OnKeyBoardDown OnKeyBoardUp=yui_getaddfreeid :OnKeyBoardUp OnClick=yui_getaddfreeid :OnClick OnDoubleClick=yui_getaddfreeid :OnDoubleClick OnRender=yui_getaddfreeid :OnRender OnActive=yui_getaddfreeid :OnActive OnLoseActive=yui_getaddfreeid :OnLoseActive OnCommand=yui_getaddfreeid :OnCommand end class UIFrame @@events=[] def self.yui_addEvent(event,method,first=false) @@events<<{"Event"=>event,"method"=>method,"first"=>first,"src"=>self} end end class EventMessage attr_reader :cb def initialize(cb) @cb=cb end def get(name) return @cb[name] end def set(name,data) @cb[name]=data end end class EventResult attr_accessor :result attr_accessor :cancel def initialize(&cb) cb.call(self) end end class UIFrame attr_accessor :need_render attr_accessor :theme def topparent return @parent.topparent end def initialize(selfo,*args) @events=[] @need_render=true for i in @@events next unless self.kind_of?(i["src"]) @events[i["Event"]]=[] if @events[i["Event"]].nil? if ((i["method"].is_a?(Symbol)) or (i["method"].is_a?(String))) @events[i["Event"]]<<[method(i["method"]),i["first"]] else @events[i["Event"]]<<[i["method"],i["first"]] end end @selfObject=selfo startEvent(YUI::Events::OnCreate,self,EventMessage.new({:args=>args})) end def myName return @selfObject.to_s end def addEvent(event,cb,first=false) @events[event]=[] if @events[event].nil? @events[event]<<[cb,first] end def realrect @r=@parent.realrect @crect=Rect.new(@r.x+@rect.x,@r.y+@rect.y,@rect.width,@rect.height) return @crect end def OnCreate(sender,e) return false end def OnDispose(sender,e) return false end def OnMouseMove(sender,e) return false end def OnMouseDown(sender,e) return false end def OnMouseUp(sender,e) return false end def OnMouseOver(sender,e) return false end def OnMouseLeave(sender,e) return false end def OnKeyBoardDown(sender,e) return false end def OnKeyBoardUp(sender,e) return false end def OnClick(sender,e) return false end def OnDoubleClick(sender,e) return false end def OnRender(sender,e) return false end def OnActive(sender,e) return false end def OnLoseActive(sender,e) return false end def startEvent(ent,sender,e) if not @events[ent].nil? for i in @events[ent] if (i[1]) return if i[0].call(sender,e) end end end method(Events::Ents[ent]).call(sender,e) if not @events[ent].nil? for i in @events[ent] unless (i[1]) return if i[0].call(sender,e) end end end end end end=begin
YUI::Window * It'a Frame that can include Page. It has own SpriteList. =end module YUI class Window < UIFrame @@rect=[] def self.yui_set_rect(rect) @@rect<<[rect,self] end end end if $摸你傻效果开关,慎用! module YUI class UISprite attr_accessor :x attr_accessor :y attr_accessor :bitmap attr_accessor :z end end else YUI::UISprite=Sprite end module YUI class Window < UIFrame attr_reader :rect attr_reader :sprite attr_reader :ncbackground attr_reader :background attr_reader :pages attr_reader :activeid attr_reader :childrect attr_accessor :bak_bitmap attr_accessor :contentOpacity @@title=[] @@pages={} @@defaultpage=[] def self.yui_addPage(name , page , &proc) #@@pages={} if @@pages[self].nil? @@pages[name]=[page,proc,self] end def topparent return self end def addPage(name,page,&proc) @pages[name]=page.new(page,proc,self,@childrect) end def changPage(name) if @page.startEvent(YUI::Events::OnLoseActive,self,YUI::EventMessage.new({})) @page=@pages[name] @page.startEvent(YUI::Events::OnActive,self,YUI::EventMessage.new({})) @need_render=true end end def self.yui_set_default_page(name) for i in @@defaultpage if i[1]==self i[0]=[name,self] return end end @@defaultpage<<[name,self] end def self.yui_set_title(name,font=:Normally) for i in @@title if i[1]==self i[0]=[[name,font],self] end end @@title<<[[name,font],self] end yui_set_title "undefined" def setTitle(name,font=:Normally) @title=[name,font] @need_render=true end def set_render(render) @need_render=render end def onWindowMouseMove(sender,e) @page.startEvent(YUI::Events::OnMouseMove,Mouse,YUI::EventMessage.new({})) end yui_addEvent Events::OnMouseMove ,:onWindowMouseMove ,true def onWindowMouseDown(sender,e) @page.startEvent(YUI::Events::OnMouseDown,Mouse,YUI::EventMessage.new({})) end yui_addEvent Events::OnMouseDown ,:onWindowMouseDown ,true def realrect return @rect end def onWindowRender(sender,e) if @ncbackground.nil? YUI::Themes.draw(:WindowNCBackGround,self,e.get(:bitmap),@active,@title) else e.get(:bitmap).fill_rect(0,0,rect.width,rect.height,@ncbackground) end if @background.nil? YUI::Themes.draw(:WindowBackGround,self,e.get(:bitmap)) else e.get(:bitmap).fill_rect(0,0,rect.width,rect.height,@background) end unless @page.nil? # p @rect @pagebit=Bitmap.new(@childrect.width,@childrect.height) @msg=YUI::EventMessage.new ({:bitmap=>@pagebit,:childrect=>@childrect}) @page.startEvent(YUI::Events::OnRender,self,@msg ) e.get(:bitmap).stretch_blt(@msg.get(:childrect),@msg.get(:bitmap),Rect.new(0,0,@msg.get(:bitmap).width,@msg.get(:bitmap).height),@contentOpacity) @msg.get(:bitmap).dispose end return false end def setThemeData @contentOpacity=Themes.get(:WindowContentOpcity,self) @childrect=Rect.new(Themes.get(:CL,self),Themes.get(:CT,self),@rect.width-Themes.get(:CL,self)-Themes.get(:CR,self),@rect.height-Themes.get(:CT,self)-Themes.get(:CB,self)) for i in @pages.keys @pages[i].rect=@childrect end end yui_addEvent Events::OnRender ,:onWindowRender ,true def onWindowCreate(sender,e) @theme={} @sprite = UISprite.new(UIManager.viewport) if e.get(:args)[0].is_a?(Rect) @rect=e.get(:args)[0] else for i in @@rect if i[1]==@selfObject @rect=i[0] end end end for i in @@title if i[1]==@selfObject @title=i[0] end end @childrect=Rect.new(Themes.get(:CL,self),Themes.get(:CT,self),@rect.width-Themes.get(:CL,self)-Themes.get(:CR,self),@rect.height-Themes.get(:CT,self)-Themes.get(:CB,self)) e.get(:args)[1].call(sender,e,self) if (e.get(:args)[1].is_a?(Proc)) @pages={} for i in @@pages.keys if @@pages[i][2]==@selfObject @pages[i]=@@pages[i][0].new(@@pages[i][0],@@pages[i][1],self,@childrect) end end for i in @@defaultpage if i[1]==@selfObject @page=@pages[i[0]] end end setThemeData @need_render=true #相对Rect坐标 return false end yui_addEvent Events::OnCreate ,:onWindowCreate ,true def onWindowActive(sender,e) return false end yui_addEvent Events::OnActive ,:onWindowActive ,true def onWindowLoseActive(sender,e) return false end yui_addEvent Events::OnLoseActive ,:onWindowLoseActive ,true end endmodule YUI
#Container和Window的区别在于,Window的构造是在模块中进行的,而Container是在 #Create中进行的。 #Rect 全部是相对父容器的Rect class Container<UIFrame attr_accessor :rect def addControler(name,controler,rect,*args,&proc) @controlers[name]=controler.new(controler,proc,self,rect,*args) set_render(true) end def addPanel(name,panel,rect,&proc) @panels[name]=panel.new(proc,self,rect) set_render(true) end def getControlerByName(name) return @controlers[name] end def getPanelByName(name) return @panels[name] end def disposePanel(panel) rst = YUI::EventResult.new{|o|o.cancel=false} panel.startEvent(YUI::Events::OnDispose,self,YUI::EventMessage.new({:result=>rst}) ) if rst.cancel==true return false else @panels.delete(panel) set_render(true) return true end end def disposeControler(controler) rst = YUI::EventResult.new{|o|o.cancel=false} controler.startEvent(YUI::Events::OnDispose,self,YUI::EventMessage.new({:result=>rst}) ) if rst.cancel==true return false else @controlers.delete(controler) set_render(true) return true end end def set_render(render) @need_render=render @parent.set_render(render) end def onContainerCreate(sender,e) args=e.get(:args) @panels={} @controlers={} @parent=args[1] @rect=args[2] set_render true args[0].call(self) return false end yui_addEvent Events::OnCreate ,:onContainerCreate ,true def onContainerRender(sender,e) for i in @controlers.keys bitmap=Bitmap.new(@controlers[i].rect.width,@controlers[i].rect.height) @msg=YUI::EventMessage.new ({:bitmap=>bitmap}) @controlers[i].startEvent(YUI::Events::OnRender,self,@msg ) e.get(:bitmap).stretch_blt(@controlers[i].rect,@msg.get(:bitmap),Rect.new(0,0,@controlers[i].rect.width,@controlers[i].rect.height)) bitmap.dispose end return false end yui_addEvent Events::OnRender ,:onContainerRender ,true def onContainerMouseMove(sender,e) for i in @controlers.keys @controlers[i].startEvent(YUI::Events::OnMouseMove,sender,e) end for i in @panels.keys @panels[i].startEvent(YUI::Events::OnMouseMove,sender,e) end return false end yui_addEvent Events::OnMouseMove ,:onContainerMouseMove ,true def onContainerMouseDown(sender,e) for i in @controlers.keys @controlers[i].startEvent(YUI::Events::OnMouseDown,sender,e) end for i in @panels.keys @panels[i].startEvent(YUI::Events::OnMouseDown,sender,e) end return false end yui_addEvent Events::OnMouseDown ,:onContainerMouseDown ,true end end=begin
module YUI class Page < Container end end =end YUI::Page=YUI::Containermodule YUI
endmodule YUI
class Controler<UIFrame def set_render(render) @need_render=render @parent.set_render(render) end def onContainerCreate(sender,e) args=e.get(:args) @parent=args[1] @rect=args[2] @mousein=false set_render true args[0].call(self) return false end def rect return @rect end def onControlerMouseMove(sender,e) if realrect.inarea?(Mouse.pos) if not @mousein @mousein=true startEvent(Events::OnMouseOver,sender,e) end elsif @mousein @mousein=false startEvent(Events::OnMouseLeave,sender,e) end return false end yui_addEvent Events::OnMouseMove ,:onControlerMouseMove ,true yui_addEvent Events::OnCreate ,:onContainerCreate ,true end endmodule YUI
class Textarea<Controler def text set_render true return @text end def text=(v) @text=v set_render true end def font set_render true return @font end def font=(f) @font=f set_render true end def onTextareaCreate(sender,e) args=e.get(:args) @text=args[3] if @text.nil? @text="" if @text.nil? @font=Font.new if @font.nil? return false end yui_addEvent Events::OnCreate ,:onTextareaCreate ,true def onTextareaRender(sender,e) bitmap=e.get(:bitmap) bitmap.clear bitmap.font=@font @x=0 @y=0 @maxheight=0 #@text.each_byte{|b| for i in 0...@text.size b=@text[i] if b!="\r" @size=bitmap.text_size(b) @maxheight = 0 if @maxheight.nil? @maxheight=[@maxheight,@size.height].max if (@x+@size.width>@rect.width) or b=="\n" @x=0 @y+=@maxheight @maxheight=0 end bitmap.draw_text(@x,@y,@size.width*2+1,@size.height+1,b) if b!="\n" @x+=@size.width if b!="\n" end end #} return false end yui_addEvent Events::OnRender ,:onTextareaRender ,true end endmodule YUI
class Button < Textarea YUI::Themes.regnewfunc(:ButtonDraw){|name,bitmap,action,flag| bitmap.gradient_fill_rect(0,0,bitmap.width,bitmap.height,Color.new(40,45,210),Color.new(8,10,140),true) bitmap.gradient_fill_rect(1,1,bitmap.width-2,bitmap.height-2,Color.new(60,67,230),Color.new(20,25,120),true) } def onTextareaCreate(sender,e) @action=:Nomorlly @flag = e.get(:args)[4] @callback=e.get(:args)[5] super(sender,e) end def onTextareaRender(sender,e) super(sender,e) bitmap=e.get(:bitmap) bitmap1=Bitmap.new(bitmap.width,bitmap.height) YUI::Themes.draw(:ButtonDraw,self.topparent,bitmap1,@action,@flag) bitmap1.blt(5,3,bitmap,Rect.new(0,0,bitmap.width,bitmap.height)) if @action==:Moving b=Bitmap.new(bitmap.width,bitmap.height) b.fill_rect(0,0,bitmap1.width,bitmap1.height,Color.new(255,255,255,255)) bitmap1.blt(0,0,b,Rect.new(0,0,bitmap.width,bitmap.height),50) end bitmap.dispose e.set(:bitmap,bitmap1) end def onButtonMouseOver(sender,e) unless @action==:Disabled @action=:Moving set_render true end return false end def onButtonMouseLeave(sender,e) unless @action==:Disabled @action=:Nomorlly set_render true end return false end yui_addEvent Events::OnMouseOver,:onButtonMouseOver,true yui_addEvent Events::OnMouseLeave,:onButtonMouseLeave,true def onButtonMouseDown(sender,e) if realrect.inarea?(Mouse.pos) p "ok?" startEvent(Events::OnCommand,self,e) end return false end yui_addEvent YUI::Events::OnMouseDown,:onButtonMouseDown,true def onButtonCommand(sender,e) @callback.call(sender,e) return false end yui_addEvent Events::OnCommand,:onButtonCommand,true end endmodule UIManager
module_function class Easy @@windowList={} def self.yui_addEasyMaker(name,clasname) @@windowList[name]=clasname end end class MessageWindow < YUI::Window end Easy.yui_addEasyMaker :MessageWindow,MessageWindow class JsonWindow < YUI::Window end Easy.yui_addEasyMaker :JsonWindow,JsonWindow endclass MyWindow < YUI::Window
yui_set_rect Rect.new(80,70,300,350) yui_set_title "My Window Test1" yui_addPage(:Page1,YUI::Page){|my| my.addControler(:TextArea1,YUI::Textarea,Rect.new(5,5,300-64,120),"\\Hello World/\n\r\\YUI/!中文测试。。自动换行测试。。"){ |my1| my1.font=Font.new("微软雅黑",24) my1.font.shadow=true my1.font.bold = true } my.addControler(:Button1,YUI::Button,Rect.new(5,200,60+4,26+4+30),"\\按钮/\n两行",:First,proc{|sender,e| UIManager.disposeWindow(my.topparent) }){ |my1| my1.font=Font.new("微软雅黑",24) my1.font.shadow=true my1.font.bold = true } } yui_set_default_page :Page1 end class MyWindow1 < YUI::Window yui_set_rect Rect.new(80+32,70+32,300,350) yui_set_title "My Window Test2" end UIManager.createWindow(MyWindow) #UIManager.createWindow(MyWindow,Rect.new(80+32,70+32,300,350)) UIManager.createWindow(MyWindow1,Rect.new(80+32,70+32,300,350),proc{|sender,e,my|my.theme[:CL],my.theme[:CR],my.theme[:CB]=16,16,16;}) #UIManager.createWindow(MyWindow1) =begin TO BE CONTINUE UIManager.createWindowMaker("json","xxx.json") {|my| addListen(getOOByName:button,YUI::Controler::Button){|sender,e| UIManager.createWindowMaker("messageBox","Hi","欢迎使用|cffff00ffYUI界面核心",UIManager::Msgbox::MSG_OKAY | UIManager::Msgbox::MSG_CANCEL) {|sender1,e1| if (e1.get(:result)==UIManager::Msgbox::MSG_OKAY) (my.getOOByName:label).setCaption("确定") else (my.getOOByName:label).setCaption("不确定") end } } =end
2014年1月25日 02:41
嗯, 这就把Win32API写死了的说= =