赞 | 0 |
VIP | 0 |
好人卡 | 0 |
积分 | 1 |
经验 | 3470 |
最后登录 | 2016-8-29 |
在线时间 | 46 小时 |
Lv1.梦旅人
- 梦石
- 0
- 星屑
- 50
- 在线时间
- 46 小时
- 注册时间
- 2014-2-4
- 帖子
- 20
|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有帐号?注册会员
x
本帖最后由 951121 于 2014-2-10 02:14 编辑
![]()
只要輸入文字,按空白鍵或是ENTER選取
就會變成這樣
![]()
可以請教大家這是為什麼嗎?
繁中輸入悲劇(艸)
腳本奉上
module Sword #======================================= #★ 魔劍工舖 - 中文輸入法(0) # [url]http://blog.yam.com/a870053jjkj/[/url] #======================================= =begin ● 所需腳本 魔劍工舖整合腳本(3):[url]http://blog.yam.com/a870053jjkj/article/25751998[/url] 全鍵盤按鍵(4):[url]http://blog.yam.com/a870053jjkj/article/24190989[/url] ======================================== ● 設置腳本 生成文字輸入框[C]:文字輸入框 = Input_Method.new(字數限制&, 行數限制&, 行距&, 視口&) 更新文字輸入框[R]:文字輸入框.update 文字輸入框內容[A]:文字輸入框.text 文字輸入框X座標[A]:文字輸入框.x 文字輸入框Y座標[A]:文字輸入框.y 文字輸入框Z座標[A]:文字輸入框.z 文字輸入框活動狀態[A]:文字輸入框.active 文字輸入框顯示狀態[A]:文字輸入框.visible 每行間的行距[A]:文字輸入框.row_spacing 設置密碼符號[A]:文字輸入框.cipher 注音和選字窗口位置類型[A]:文字輸入框.win_seat 文字游標位置[A]:文字輸入框.index 文字游標行數[A]:文字輸入框.row Enter鍵是否空閒[R]:文字輸入框.enter? 已輸入內容寬度[R]:文字輸入框.width 已輸入內容高度[R]:文字輸入框.height 待確認內容確認[R]:文字輸入框.decision 關閉文字輸入框[R]:文字輸入框.dispose 更新輸入法狀態[R]:Input_Method.update 鎖定輸入法[R]:Input_Method.lock(輸入法類型&) 設置輸入法狀態窗口[R]:Input_Method.statu(X座標&, Y座標&) 釋放輸入法狀態窗口[R]:Input_Method.statu_dispose ---------------------------------------- 輸入法類型:0為注音、1為英文 窗口位置類型:1為左下、2為下、3為右下、7為左上、8為上、9為右上 =end #======================================= #● 功能設定 S84_Horizontal = false # 注音輸入框的顯示方式,true表示橫式;false表示直式 S84_Decision = true # 是否啟用待確認內容功能 S84_Default = [Font.new('細明體'), 3] # 文字輸入框預設的 [字體, 窗口位置類型] S84_Cursor = [0, 1, true] # 文字游標的 [類型, 厚度, 允許更換] S84_Phonetic = [Font.new('標楷體', 16), 0, 0] # 注音輸入框的 [字體, X修正, Y修正] S84_Choose = [80, 4, Font.new('細明體', 16)] # 選字窗口的 [寬度, 行距, 字體] #--------------------------------------- # 字體:可設定Font對象『Font.new('字體名稱', 大小)』或nil使用預設字體 #======================================= $Sword ? $Sword[18] = [:中文輸入法, 0] : $Sword = {18=>[:中文輸入法, 0]} end #======================================= #■ 注音輸入框 class WSword_Phonetic < Window_Base attr_accessor(:phonetic) # 已輸入注音內容 attr_accessor(:win_choose) # 關連選字窗口 attr_accessor(:alter) # 修改標誌 # 注音表 Phonetic = { 49=>'ㄅ', 81=>'ㄆ', 65=>'ㄇ', 90=>'ㄈ', 50=>'ㄉ', 87=>'ㄊ', 83=>'ㄋ', 88=>'ㄌ', 69=>'ㄍ', 68=>'ㄎ', 67=>'ㄏ', 82=>'ㄐ', 70=>'ㄑ', 86=>'ㄒ', 53=>'ㄓ', 84=>'ㄔ', 71=>'ㄕ', 66=>'ㄖ', 89=>'ㄗ', 72=>'ㄘ', 78=>'ㄙ', 85=>'ㄧ', 74=>'ㄨ', 77=>'ㄩ', 56=>'ㄚ', 73=>'ㄛ', 75=>'ㄜ', 188=>'ㄝ', 57=>'ㄞ', 79=>'ㄟ', 76=>'ㄠ', 190=>'ㄡ', 48=>'ㄢ', 80=>'ㄣ', 186=>'ㄤ', 191=>'ㄥ', 189=>'ㄦ', 32=>' ', 54=>'ˊ', 51=>'ˇ', 52=>'ˋ', 55=>'˙'} #------------------------------------------------------ #● 初始化 def initialize super(16, 16, 64, 64) self.contents = Bitmap.new(1, 1) @phonetics = ['', '', '', ''] # [前, 中, 後, 聲] @phonetic = '' @alter = false # 修改標誌 @font = Sword::S84_Phonetic[0] ? Sword::S84_Phonetic[0].clone : Font.new self.visible, self.z = false, 300 end #------------------------------------------------------ #● 更新內容 def refresh phonetics = @phonetic.scan(/./) # 分解字串 return self.visible = false if phonetics.empty? # 沒輸入就不顯示 size = @font.size # 獲取字體大小 self.visible = true if Sword::S84_Horizontal # 橫式 self.width = contents.text_size(@phonetic).width + 32 self.height = size + 32 self.contents = Bitmap.new(width - 32, height - 32) contents.font = @font contents.draw_text(0, 0, width - 32, size, @phonetic) else # 直式 self.width = size + 32 self.height = phonetics.size * size + 32 self.contents = Bitmap.new(width - 32, height - 32) contents.font = @font phonetics.each_index{|i| contents.draw_text(0, size * i, size, size, phonetics[i])} end end #------------------------------------------------------ #● 添加(注音鍵值) def add(key) return if @win_choose.visible # 選字窗口顯示時不可變更 @alter = false case key when 49,81,65,90,50,87,83,88,69,68,67,82,70,86,53,84,71,66,89,72,78 then @phonetics[3], a = '', 0 # 前 when 85,74,77 then @phonetics[3], a = '', 1 # 中 when 56,73,75,188,57,79,76,190,48,80,186,191,189 then @phonetics[3], a = '', 2 # 後 when 32,54,51,52,55 then a = 3 # 聲 else return # 非合理內容 end @phonetics[a] = Phonetic[key] @phonetic = @phonetics.to_s refresh if a == 3 # 活化選字窗口 @win_choose.refresh(@phonetic) end end #------------------------------------------------------ #● 指定注音(注音) def set(phonetic) @alter = true @phonetic = phonetic refresh @win_choose.refresh(@phonetic, true) end #------------------------------------------------------ #● 清除(全部清除) def remove(whole = false) if whole # 全部清除 @phonetics = ['', '', '', ''] else # 尾字清除 [3, 2, 1, 0].each{|i| (@phonetics[i] = '' ; break) unless @phonetics[i].empty?} end @phonetic = @phonetics.to_s refresh @win_choose.visible = false end end #======================================= #■ 選字窗口 class WSword_ChooseWord < Window_Selectable attr_accessor(:direct) # 直接輸入的字 #------------------------------------------------------ #● 初始化 def initialize @font = Sword::S84_Choose[2] ? Sword::S84_Choose[2].clone : Font.new super(0, 0, Sword::S84_Choose[0], (@font.size + Sword::S84_Choose[1]) * 11 + 32) self.contents = Bitmap.new(width - 32, height - 32) contents.font = @font @page = 0 # 頁數 @key = '' # 當前輸入注音 @direct = nil # 無需選字時要直接輸出的字(只有1個字時才用) self.visible, self.z = false, 300 @chinese = Chinese rescue raise('找不到字庫,請檢查是否有已經放置字庫腳本') # 讀取字庫 end #------------------------------------------------------ #● 更新內容(注音, 修改標誌) def refresh(phonetic = nil, alter = false) if phonetic # 讀取新資料 return RM.se_buzzer unless @chinese[phonetic] # 資料庫未找到該注音的資料時 return @direct = @chinese[phonetic][0] if @chinese[phonetic].size == 1 && ! alter # 直接輸入 @key = phonetic @page = 0 @index = 0 self.visible = true end contents.clear i = 0 size = @font.size w = (Sword::S84_Choose[0] - 32) / 2 sa = Sword::S84_Choose[1] + size # 開始描繪每個選項的字 @chinese[@key][@page * 10, 10].each do |c| contents.draw_text(0, i * sa, w, sa, (i == 9 ? 0 : i + 1).to_s, 1) contents.draw_text(w, i * sa, w, sa, c, 1) i += 1 end @item_max = i @page_size = @chinese[@key].size / 10 - (@chinese[@key].size % 10 == 0 ? 1 : 0) # 頁數上限 contents.draw_text(0, height - 32 - size, width - 32, size, "#{@page + 1}/#{@page_size + 1}", 1) end #------------------------------------------------------ #● 更新游標 def update_cursor_rect cursor_rect.set(0, (Sword::S84_Choose[1] + @font.size) * @index, width - 32, Sword::S84_Choose[1] + @font.size) end def update_cursor update_cursor_rect end #------------------------------------------------------ #● 更新 def update super choose = nil # 代表確定選擇的項目 if Input.trigger?(37) # 左一頁 @page -= 1 @page = @page_size if @page < 0 refresh @index = @item_max - 1 if @index >= @item_max # 換頁時游標位置修正 RM.se_cursor elsif Input.trigger?(39) # 右一頁 @page += 1 @page = 0 if @page > @page_size refresh @index = @item_max - 1 if @index >= @item_max RM.se_cursor elsif Input.trigger?([13, 32]) # 確定(空白、ENTER) choose = @index end (48..57).each{|i| choose = i == 48 ? 9 : i - 49 if Input.trigger?(i)} unless choose # 左數字鍵 (96..105).each{|i| choose = i == 96 ? 9 : i - 97 if Input.trigger?(i)} unless choose # 右數字鍵 if choose # 確認選擇 return nil unless c = @chinese[@key][@page * 10, 10][choose] # 結果確認 self.visible = false return c # 返回結果 end nil # 尚未選字代表的返回值 end end #======================================= #■ 輸入法窗口 class Input_Method attr_reader(:x) # X座標 attr_reader(:y) # Y座標 attr_reader(:z) # Z座標 attr_reader(:index) # 索引 attr_reader(:row) # 行數 attr_reader(:visible) # 隱藏狀態 attr_reader(:win_seat) # 窗口位置類型 attr_reader(:windowskin) # 窗口皮膚 attr_accessor(:cipher) # 密碼 attr_accessor(:font) # 字體 attr_accessor(:imports) # 當前輸入的內容 attr_accessor(:row_spacing) # 行距 Kind_Max = 2 # 輸入法數量 Phonetic_keys = WSword_Phonetic::Phonetic.keys # 符號資料庫(左方鍵盤用) Tilde = { # 半形 48=>')', 49=>'!', 50=>'@', 51=>'#', 52=>'$', 53=>'%', 54=>'^', 55=>'&', 56=>'*', 57=>'(', 186=>':', 187=>'+', 188=>'<', 189=>'_', 190=>'>', 191=>'?', 192=>'~', 219=>'{', 220=>'|', 221=>'}', 222=>'"'} TILDE = { # 全形 48=>')', 49=>'!', 50=>'@', 51=>'#', 52=>'$', 53=>'%', 54=>'︿', 55=>'&', 56=>'*', 57=>'(', 186=>':', 187=>'+', 188=>'<', 189=>'_', 190=>'>', 191=>'?', 192=>'~', 219=>'{', 220=>'|', 221=>'}', 222=>'"'} Tilde_keys = Tilde.keys # 符號資料庫(右方鍵盤用+空白鍵) TildeR = { # 半形 32=>' ', 96=>'0', 97=>'1', 98=>'2', 99=>'3', 100=>'4', 101=>'5', 102=>'6', 103=>'7', 104=>'8', 105=>'9', 106=>'*', 107=>'+', 109=>'-', 110=>'.', 111=>'/'} TILDER = { # 全形 32=>' ', 96=>'0', 97=>'1', 98=>'2', 99=>'3', 100=>'4', 101=>'5', 102=>'6', 103=>'7', 104=>'8', 105=>'9', 106=>'*', 107=>'+', 109=>'-', 110=>'。', 111=>'/'} TildeR_keys = TildeR.keys # 中文聲符 Pho_Voice = {32=>' ', 54=>'ˊ', 51=>'ˇ', 52=>'ˋ', 55=>'˙'} # 英文大寫資料庫(半) English = { 65=>'A', 66=>'B', 67=>'C', 68=>'D', 69=>'E', 70=>'F', 71=>'G', 72=>'H' ,73=>'I', 74=>'J', 75=>'K', 76=>'L', 77=>'M', 78=>'N', 79=>'O', 80=>'P', 81=>'Q' ,82=>'R', 83=>'S', 84=>'T', 85=>'U', 86=>'V', 87=>'W', 88=>'X', 89=>'Y', 90=>'Z', 48=>'0', 49=>'1', 50=>'2', 51=>'3', 52=>'4', 53=>'5', 54=>'6', 55=>'7', 56=>'8', 57=>'9', 191=>'/', 186=>';', 187=>'=', 188=>',', 189=>'-', 190=>'.', 191=>'/', 192=>'`', 219=>'[', 220=>'\\', 221=>']', 222=>'\''} English_keys = English.keys # 英文小寫資料庫(半) English_small = { 65=>'a', 66=>'b', 67=>'c', 68=>'d', 69=>'e', 70=>'f', 71=>'g', 72=>'h' ,73=>'i', 74=>'j', 75=>'k', 76=>'l', 77=>'m', 78=>'n', 79=>'o', 80=>'p', 81=>'q' ,82=>'r', 83=>'s', 84=>'t', 85=>'u', 86=>'v', 87=>'w', 88=>'x', 89=>'y', 90=>'z', 48=>'0', 49=>'1', 50=>'2', 51=>'3', 52=>'4', 53=>'5', 54=>'6', 55=>'7', 56=>'8', 57=>'9', 191=>'/', 186=>';', 187=>'=', 188=>',', 189=>'-', 190=>'.', 191=>'/', 192=>'`', 219=>'[', 220=>'\\', 221=>']', 222=>'\''} # 英文大寫資料庫(全) ENGLISH = { 65=>'A', 66=>'B', 67=>'C', 68=>'D', 69=>'E', 70=>'F', 71=>'G', 72=>'H' , 73=>'I', 74=>'J', 75=>'K', 76=>'L', 77=>'M', 78=>'N', 79=>'O', 80=>'P', 81=>'Q', 82=>'R', 83=>'S', 84=>'T', 85=>'U', 86=>'V', 87=>'W', 88=>'X', 89=>'Y', 90=>'Z', 48=>'0', 49=>'1', 50=>'2', 51=>'3', 52=>'4', 53=>'5', 54=>'6', 55=>'7', 56=>'8', 57=>'9', 186=>';', 187=>'=', 188=>',', 189=>'-', 190=>'。', 191=>'/', 192=>'‵', 219=>'[', 220=>'\', 221=>']', 222=>'’'} # 英文小寫資料庫(全) ENGLISH_SMALL = { 65=>'a', 66=>'b', 67=>'c', 68=>'d', 69=>'e', 70=>'f', 71=>'g', 72=>'h' , 73=>'i', 74=>'j', 75=>'k', 76=>'l', 77=>'m', 78=>'n', 79=>'o', 80=>'p', 81=>'q', 82=>'r', 83=>'s', 84=>'t', 85=>'u', 86=>'v', 87=>'w', 88=>'x', 89=>'y', 90=>'z', 48=>'0', 49=>'1', 50=>'2', 51=>'3', 52=>'4', 53=>'5', 54=>'6', 55=>'7', 56=>'8', 57=>'9', 186=>';', 187=>'=', 188=>',', 189=>'-', 190=>'。', 191=>'/', 192=>'‵', 219=>'[', 220=>'\', 221=>']', 222=>'’',} @@caps_lock = @@fully = false # 大寫標誌, 全形標誌 @@fully_true = false # 全形標誌變更標誌 @@kind, @@lock = 0, [] # 輸入法種類, 鎖定的輸入法種類 @@win_method_statu = nil # 輸入法狀態窗口 @@manage = {} # 已生成文字輸入框列表 @@active = nil # 正在活動對象 @@win_choose = @@win_phonetic = nil # 選字窗口, 注音輸入框 #------------------------------------------------------ #● 初始化(字數限制, 行數限制, 視口) def initialize(max = 0, row_max = 0, viewport = nil) if @@manage.empty? # 未存在文字輸入窗時就生成 @@win_choose = WSword_ChooseWord.new # 選字窗口 @@win_phonetic = WSword_Phonetic.new # 注音輸入框 @@win_phonetic.win_choose = @@win_choose # 關連 end @@manage[self.__id__] = self # 加入列表 @viewport = viewport # 視口 @font = Sword::S84_Default[0] ? Sword::S84_Default[0].clone : Font.new # 字體 @cipher = '' # 密碼符號 @imports = [[]] # 每行當前輸入的單個文字 @show = [[]] # 用於顯示於文字輸入框的文字 @index = @row = @row_spacing = 0 # 索引、行數、行距 @insert = Sword::S84_Cursor[0] # 文字游標類型 @max = max # 字數限制 @row_max = row_max # 最大行數 @win_seat = Sword::S84_Default[1] # 窗口位置類型 @cursor_size = [0, 0] # 文字游標 [寬度, 高度] @avail = [] # 按鍵無效列表 [Enter, 聲符(包含右邊小鍵盤), 空白] @affirm = [0, 0, [], 0, 0] # 等待確認輸入 [X座標, Y座標, 注音, 起始, 終點] @windowskin = nil # 窗口皮膚 @spr_import = Sprite.new(@viewport) # 輸入窗口 @spr_import.bitmap = Bitmap.new(1, 1) # 一開始計算單個字寬度用的位圖 @spr_cursor = Sprite.new(@viewport) # 文字游標 @spr_cursor.bitmap = Bitmap.new(50, 50) @cursor_update = 0 # 文字游標的閃爍計數 self.x, self.y, self.z = 0, 0, 200 self.active = @@active.nil? # 活動對象(第1個文字輸入框有效) @visible = true # 顯示狀態 end #------------------------------------------------------ #● 獲取文字 def text text = '' @imports.each{|import| text += import.to_s + "\n"} text[-1] = '' text end #------------------------------------------------------ #● 修改文字=(新文字) def text=(text) @imports = [[]] # 清空 i = 0 text.split(/\n/).each do |item| @imports[i] = item.scan(/./) i += 1 end refresh cursor_refresh end #------------------------------------------------------ #● 獲取已輸入內容的寬度 def width return @cursor_size[0] if @spr_import.bitmap.width == 1 # 沒有文字就返回0 @spr_import.bitmap.width + (self.index == @imports[@row].size ? @cursor_size[0] : 0) end #------------------------------------------------------ #● 獲取已輸入內容的高度 def height @spr_import.bitmap.height + (@imports[@row + 1] ? 0 : @cursor_size[1]) end #------------------------------------------------------ #● 設定X座標=(新X座標) def x=(x) @spr_import.x = @x = x @spr_cursor.x = x + @spr_import.bitmap.text_size(@imports[@row][0, @index].to_s).width win_phonetic_seat end #------------------------------------------------------ #● 設定Y座標=(新Y座標) def y=(y) @spr_import.y = @y = y @spr_cursor.y = y + @row * (@font.size + @row_spacing) win_phonetic_seat end #------------------------------------------------------ #● 設定Z座標=(新Z座標) def z=(z) @spr_import.z = @spr_cursor.z = @z = z end #------------------------------------------------------ #● 變更索引=(新索引) def index=(index) if @affirm[2].empty? @index = [[index, @imports[@row].size].min, 0].max else @index = [[index, @affirm[4] + 1].min, @affirm[3]].max end cursor_refresh end #------------------------------------------------------ #● 獲取活動狀態 def active equal?(@@active) ? true : false end #------------------------------------------------------ #● 變更窗口位置類型 def win_seat=(win_seat) @win_seat = win_seat win_phonetic_seat end #------------------------------------------------------ #● 變更活動狀態=(活動標誌) def active=(active) @spr_cursor.visible = active if active && ! self.active # 不處於活動狀態的輸入框設為true if @@active # 如果有其他的文字輸入框活動的情況 @@win_phonetic.remove(true) @@win_choose.visible = false @@active.decision @@active.active = false end @@active = self @spr_cursor.visible = true cursor_refresh elsif ! active && self.active # 處於活動狀態的輸入框設為false @@active = nil end end #------------------------------------------------------ #● 隱藏狀態變更=(隱藏標誌) def visible=(visible) @spr_cursor.visible = @spr_import.visible = @visible = visible end #------------------------------------------------------ #● 變更行數=(新行數) def row=(row) @row = [row, 0].max @row = [@row, @row_max - 1].min if @row_max > 0 cursor_refresh end #------------------------------------------------------ #● 可以輸入判斷(準備添加的字) def import?(c = '') return true if @max == 0 # 無限制的場合 if @max > 0 # 字數 n = -1 # 字數計數 @imports.each{|imports| n += 1 ; n += imports.size} n += 1 unless c.empty? else ; n = (text + c).size # 字元數 end return @max.abs >= n # 返回結果 end #------------------------------------------------------ #● 可以換行判斷 def row? return true if @row_max <= 0 # 無限制的場合 return @row_max > @imports.size # 返回結果 end #------------------------------------------------------ #● 到達底行時,Enter是否可用 def enter? return false if ! @affirm[2].empty? || @@win_phonetic.visible || ! active row? ? false : (@avail[0] ? false : true) end #------------------------------------------------------ #● 更新內容 def refresh # 計算所需資料 imports, width = [], 0 # 已轉換字串文字列表, 最大寬度 @show = [[]] # 清空 @imports.each_index do |i| @show[i] = @cipher[0] ? Array.new(@imports[i].size, @cipher) : @imports[i] # 轉密碼 import = @show[i].to_s # 轉換為字串 if a = @spr_import.bitmap.text_size(import).width # 獲取這個字的寬度 width = a if a > width # 設定最大寬度 end imports << import end # 描繪文字內容 width = 1 if width == 0 # 沒有文字的情況下 row = @font.size + @row_spacing # 行距計算 @spr_import.bitmap = Bitmap.new(width, row * @show.size) # 重新產生位圖 @spr_import.bitmap.font = @font imports.each_index{|i| import = imports[i] @spr_import.bitmap.draw_text(0, row * i, width, @font.size, import)} # 描繪待確認文字虛線 unless @affirm[2].empty? width = @spr_import.bitmap.text_size(@show[@row][@affirm[3]..@affirm[4]].to_s).width x = 0 while x < width @spr_import.bitmap.fill_rect(@affirm[0] + x, @affirm[1] + @font.size - 1, 2, 1, @font.color) x += 3 end end cursor_refresh win_phonetic_seat end #------------------------------------------------------ #● 更新文字游標內容 def cursor_refresh @cursor_update = 0 return unless @spr_cursor.visible = active && visible # 移動文字游標時的顯示 @spr_cursor.x = @x + @spr_import.bitmap.text_size(@show[@row][0, @index].to_s).width @spr_cursor.y = @y + @row * (@font.size + @row_spacing) @spr_cursor.bitmap.clear @spr_cursor.bitmap.font = @font case @insert when 0 # | @spr_cursor.bitmap.fill_rect(0, 0, Sword::S84_Cursor[1], @font.size, @font.color) @cursor_size = [Sword::S84_Cursor[1], 0] when 1 # _ width = @spr_cursor.bitmap.text_size(@show[@row][@index] ? @show[@row][@index] : ' ').width @spr_cursor.bitmap.fill_rect(0, @font.size, width, Sword::S84_Cursor[1], @font.color) @cursor_size = [width, Sword::S84_Cursor[1]] end end #------------------------------------------------------ #● 更新窗口 def update return unless active # 不活動就中斷 #○ 文字游標閃爍更新 if @visible # 文字輸入框顯示時 @cursor_update += 1 # 增加游標閃爍計數 @spr_cursor.visible = ! @spr_cursor.visible if @cursor_update % 20 == 0 end #○ 任何時機均可執行處 Input_Method.update # 輸入法按鍵判斷 if Input.trigger?(45) && Sword::S84_Cursor[2] # 切換文字游標樣式 @insert = @insert == 0 ? 1 : 0 cursor_refresh elsif Input.press?(16) && Input.trigger?(32) # 切換全半形(追加處理) @avail[2] = true # 封鎖空白的使用權 end #○ 注音輸入法相關 if @@win_choose.direct # 當選字窗口只有1個字可選時直接輸入 @avail[1] = true # 封鎖聲符的使用權 add(@@win_choose.direct) @@win_phonetic.remove(true) @@win_choose.direct = nil return elsif @@win_choose.visible # 選字窗口顯示時 @avail[1] = true # 封鎖聲符的使用權 if c = @@win_choose.update # 更新結果為已經選擇文字時 add(c) @@win_phonetic.remove(true) @avail[0] = true # 封鎖Enter的使用權 end if Input.repeat?(8) then @@win_phonetic.remove # 清除一個注音 elsif Input.trigger?(27) then @@win_phonetic.remove(true) # 清除所有注音 end return elsif @@win_phonetic.visible # 注音輸入框顯示時 if Input_Method.kind != 0 # 非注音輸入法時 @@win_phonetic.remove(true) @@win_choose.visible = false return end Phonetic_keys.each do |key| if Input.trigger?(key) # 注音輸入 @@win_phonetic.add(key) win_phonetic_seat end end if Input.repeat?(8) then @@win_phonetic.remove # 清除一個注音 elsif Input.trigger?(27) then @@win_phonetic.remove(true) # 清除所有注音 end return end #○ 恢復被限制的使用權 @avail[0] = false unless Input.press?(13) if @avail[0] # 恢復Enter使用權 @avail[1] = false if Input.press?(Pho_Voice.keys + TildeR_keys, true).empty? if @avail[1] # 恢復聲符使用權 @avail[2] = false unless Input.press?(16) if @avail[2] # 恢復空白使用權 #○ 等待確認文字處理 unless @affirm[2].empty? if Input.trigger?(40) # 重新開啟選字窗口 return if @index == @affirm[4] + 1 || @affirm[2][@index - @affirm[3]] == true win_phonetic_seat @@win_phonetic.set(@affirm[2][@index - @affirm[3]]) elsif Input.trigger?(13) # 確認結果 @avail[0] = true # 封鎖Enter使用權 return decision end end #○ 不再注音輸入顯現時的按鍵執行 case when Input.repeat?(8) then remove # 清除前一個字 when Input.repeat?(46) then remove(true) # 清除後一個字 when Input.trigger?(27) then self.text = '' # 清空 when Input.repeat?(37) # 左移 return if @index == @affirm[3] unless @affirm[2].empty? if @row > 0 && self.index == 0 @row -= 1 ; self.index = @imports[@row].size else ; self.index -= 1 end when Input.repeat?(39) # 右移 return if @index == @affirm[4] + 1 unless @affirm[2].empty? if @imports[@row + 1] && self.index == @imports[@row].size @row += 1 ; self.index = 0 else ; self.index += 1 end when Input.repeat?(38) # 上移 return unless @affirm[2].empty? self.row -= 1 if @row > 0 when Input.repeat?(40) # 下移 return unless @affirm[2].empty? self.row += 1 if @imports[@row + 1] when Input.repeat?(13) && ! @avail[0] # 換行 return unless @affirm[2].empty? # 待確認內容情況 return if ! import?("\n") || ! row? # 已達限制就中斷 a = @imports[@row][@index..@imports[@row].size-1] # 獲取換到下行的文字 @imports[@row].slice!(@index..@imports[@row].size-1) # 剪下?! @row += 1 @imports[@row, 0] = [a] # 貼上?! refresh self.index = 0 # 文字游標移動行頭 end #○ 處理各個輸入法都可用的符號輸入(空白鍵和右方數字鍵) TildeR_keys.each{|key| add(Input_Method.fully ? TILDER[key] : TildeR[key]) if Input.repeat?(key)} unless @avail[1] #○ 各類輸入法的處理 case Input_Method.kind when 0 # 注音輸入 if Input.press?(192) # 按下~在按下符號鍵視同輸入全形符號 Tilde_keys.each{|key| next if key == 192 add(Input.press?(16) ? TILDE[key] : ENGLISH[key]) if Input.trigger?(key)} return elsif Input.press?(16) then return english_import # 按下Shift視同英打 end Pho_Voice.each do |key, value| # 聲符輸入開始 add(value) if Input.repeat?(key) && key != 32 # 輸入聲符 return if Input.press?(key) # 按住期間不可輸入注音 end unless @avail[1] Phonetic_keys.each do |key| if Input.trigger?(key) # 注音輸入開始 @@win_phonetic.add(key) win_phonetic_seat end end when 1 # 英文輸入 english_import # 英文輸入開始 end end #------------------------------------------------------ #● 英文輸入處理 def english_import fully, caps_lock = Input_Method.fully, Input_Method.caps_lock English_keys.each do |key| if Input.repeat?(key) press = Input.press?(16) # Shift按下確認 case when fully && TILDE[key] && press then add(TILDE[key]) # 全形符號 when Tilde[key] && press then add(Tilde[key]) # 半形符號 when fully && caps_lock != press then add(ENGLISH[key]) # 全形大寫 when fully && ! caps_lock != press then add(ENGLISH_SMALL[key]) # 全形小寫 when caps_lock != press then add(English[key]) # 半形大寫 when ! caps_lock != press then add(English_small[key]) # 半形小寫 end end end end #------------------------------------------------------ #● 添加字到文字輸入框(添加的字) def add(c) return if /[ ]/ === c if @avail[2] # 空白輸入封鎖時中斷 # 修改的場合 if @@win_phonetic.alter @@win_phonetic.alter = false @imports[@row][@index, 1] = c self.index += 1 return refresh end return unless import?(c) # 突破限制字數就中斷 # 是否可選字判斷 if Sword::S84_Decision case when buffer = Choose[c] # 符號 when buffer = @@win_phonetic.phonetic.empty? ? nil : @@win_phonetic.phonetic # 注音 when @affirm[2].size > 0 then buffer = true # 處理 end # 待確認文字處理 if buffer if @affirm[2].empty? # 尚未存在待輸入內容時 # 紀錄文字游標X座標, Y座標, 最小索引位置, 最大索引位置 @affirm[0], @affirm[1], @affirm[3], @affirm[4] = @spr_cursor.x - @x, @spr_cursor.y - @y, @index, @index - 1 end @affirm[2] << buffer @affirm[4] += 1 # 最大索引增加 end end # 直接輸出 @imports[@row][@index, 0] = c refresh self.index += 1 end #------------------------------------------------------ #● 清除(delete鍵標誌) def remove(delete = false) if delete # delete鍵 unless @affirm[2].empty? # 只能刪除待確認文字 return if @index == @affirm[4] + 1 # 游標在待確認文字最左邊就中斷 @affirm[2].delete_at(@index - @affirm[3]) @affirm[4] -= 1 end @imports[@row].delete_at(@index) cursor_refresh # 純粹更新文字游標用 else # BACKSPACE鍵 unless @affirm[2].empty? # 只能刪除待確認文字 return if @index == @affirm[3] # 游標在待確認文字最左邊就中斷 @affirm[2].delete_at(@index - @affirm[3] - 1) @affirm[4] -= 1 end if @index > 0 # 文字游標非在最左邊時 @imports[@row].delete_at(@index - 1) self.index -= 1 else # 文字游標在最左邊時 if @row > 0 # 在第2行以上的場合 a = @imports[@row] # 獲取要移動到上一行的字 @imports.delete_at(@row) # 剪下?! @row -= 1 @imports[@row] += a # 貼上?! self.index = @imports[@row].size - a.size # 文字游標移至最右邊 end end end refresh end #------------------------------------------------------ #● 確認 def decision @affirm[2].clear refresh end #------------------------------------------------------ #● 設定注音輸入框的位置(類型索引) def win_phonetic_seat(type = nil) pho, cho = @@win_phonetic, @@win_choose # 縮短名稱 pho.x = [[@spr_cursor.x + Sword::S84_Phonetic[1], RM.width - pho.width].min, 0].max pho.y = [[@spr_cursor.y + Sword::S84_Phonetic[2] + @font.size, RM.height - pho.height].min, 0].max case type ? type : @win_seat when 1 # 左側下方 cho.x = pho.x - cho.width return win_phonetic_seat(3) if cho.x < 0 cho.y = [pho.y, RM.height - cho.height].min when 2 # 下方 cho.y = pho.y + pho.height return win_phonetic_seat(8) if cho.y + cho.height > RM.height cho.x = [pho.x, RM.width - pho.width].min when 3 # 右側下方 cho.x = pho.x + pho.width return win_phonetic_seat(1) if cho.x + cho.width > RM.width cho.y = [pho.y, RM.height - cho.height].min when 7 # 左側上方 cho.x = pho.x - cho.width return win_phonetic_seat(9) if cho.x < 0 cho.y = [pho.y - cho.height + pho.height, 0].max when 8 # 上方 cho.y = pho.y - cho.height return win_phonetic_seat(2) if cho.y < 0 cho.x = [pho.x, RM.width - pho.width].min when 9 # 右側上方 cho.x = pho.x + pho.width return win_phonetic_seat(7) if cho.x + cho.width > RM.width cho.y = [pho.y - cho.height + pho.height, 0].max end end #------------------------------------------------------ #● 釋放窗口 def dispose @spr_import.dispose @spr_cursor.dispose if active # 如果釋放對象為活動窗口時 @@active = nil if @@win_phonetic.visible # 注音輸入框如果顯示,就清除掉 @@win_phonetic.remove(true) @@win_choose.visible = false end end @@manage.delete(self.__id__) # 清除紀錄 if @@manage.empty? # 文字輸入框清除光就釋放 @@win_phonetic.dispose @@win_choose.dispose end end #------------------------------------------------------ #● 設置輸入法狀態窗口(X座標, Y座標) def self.statu(x = nil, y = nil) @@win_method_statu = WSword_MethodStatu.new unless @@win_method_statu # 生成 @@win_method_statu.x = x if x @@win_method_statu.y = y if y @@win_method_statu.refresh end #------------------------------------------------------ #● 釋放輸入法狀態窗口 def self.statu_dispose return unless @@win_method_statu # 已經釋放就中斷 @@win_method_statu.dispose @@win_method_statu = nil end #------------------------------------------------------ #● 獲取輸入法號 def self.kind @@lock[0] ? @@lock[0] : @@kind end #------------------------------------------------------ #● 獲取大寫標誌 def self.caps_lock @@lock[1].nil? ? @@caps_lock : @@lock[1] end #------------------------------------------------------ #● 獲取全形標誌 def self.fully @@lock[2].nil? ? @@fully : @@lock[2] end #------------------------------------------------------ #● 鎖定輸入法(輸入法種類, 大寫標誌, 全型標誌) def self.lock(kind = nil, caps_lock = nil, fully = nil) @@lock = [kind, caps_lock, fully] @@win_method_statu.refresh if @@win_method_statu # 更新輸入法狀態窗口 end #------------------------------------------------------ #● 更新按鍵 def self.update if Input.trigger?(20) # 切換大小寫 @@caps_lock = ! @@caps_lock @@win_method_statu.refresh if @@win_method_statu # 更新輸入法狀態窗口 elsif Input.trigger?(17) # 切換輸入法 @@kind += 1 @@kind = 0 if @@kind == Kind_Max @@win_method_statu.refresh if @@win_method_statu # 更新輸入法狀態窗口 elsif Input.press?(16) && Input.trigger?(32) # 切換全半形 @@fully = ! @@fully @@win_method_statu.refresh if @@win_method_statu # 更新輸入法狀態窗口 end end end #======================================= #■ 輸入法狀態窗口 class WSword_MethodStatu < Window_Base #------------------------------------------------------ #● 初始化 def initialize super(0, 0, 96, 64) self.contents = Bitmap.new(width - 32, height - 32) end #------------------------------------------------------ #● 更新內容 def refresh contents.clear contents.draw_text(0, 0, 32, 32, Input_Method.kind == 0 ? 'ㄅ' : (Input_Method.caps_lock ? 'A' : 'a'), 1) contents.fill_rect(36, 4, 24, 24, contents.font.color) contents.fill_rect(36 + 12, 5, 11, 22, Color.new(0, 0, 0, 0)) unless Input_Method.fully end end
module Sword
#=======================================
#★ 魔劍工舖 - 中文輸入法(0)
# [url]http://blog.yam.com/a870053jjkj/[/url]
#=======================================
=begin
● 所需腳本
魔劍工舖整合腳本(3):[url]http://blog.yam.com/a870053jjkj/article/25751998[/url]
全鍵盤按鍵(4):[url]http://blog.yam.com/a870053jjkj/article/24190989[/url]
========================================
● 設置腳本
生成文字輸入框[C]:文字輸入框 = Input_Method.new(字數限制&, 行數限制&, 行距&, 視口&)
更新文字輸入框[R]:文字輸入框.update
文字輸入框內容[A]:文字輸入框.text
文字輸入框X座標[A]:文字輸入框.x
文字輸入框Y座標[A]:文字輸入框.y
文字輸入框Z座標[A]:文字輸入框.z
文字輸入框活動狀態[A]:文字輸入框.active
文字輸入框顯示狀態[A]:文字輸入框.visible
每行間的行距[A]:文字輸入框.row_spacing
設置密碼符號[A]:文字輸入框.cipher
注音和選字窗口位置類型[A]:文字輸入框.win_seat
文字游標位置[A]:文字輸入框.index
文字游標行數[A]:文字輸入框.row
Enter鍵是否空閒[R]:文字輸入框.enter?
已輸入內容寬度[R]:文字輸入框.width
已輸入內容高度[R]:文字輸入框.height
待確認內容確認[R]:文字輸入框.decision
關閉文字輸入框[R]:文字輸入框.dispose
更新輸入法狀態[R]:Input_Method.update
鎖定輸入法[R]:Input_Method.lock(輸入法類型&)
設置輸入法狀態窗口[R]:Input_Method.statu(X座標&, Y座標&)
釋放輸入法狀態窗口[R]:Input_Method.statu_dispose
----------------------------------------
輸入法類型:0為注音、1為英文
窗口位置類型:1為左下、2為下、3為右下、7為左上、8為上、9為右上
=end
#=======================================
#● 功能設定
S84_Horizontal = false # 注音輸入框的顯示方式,true表示橫式;false表示直式
S84_Decision = true # 是否啟用待確認內容功能
S84_Default = [Font.new('細明體'), 3] # 文字輸入框預設的 [字體, 窗口位置類型]
S84_Cursor = [0, 1, true] # 文字游標的 [類型, 厚度, 允許更換]
S84_Phonetic = [Font.new('標楷體', 16), 0, 0] # 注音輸入框的 [字體, X修正, Y修正]
S84_Choose = [80, 4, Font.new('細明體', 16)] # 選字窗口的 [寬度, 行距, 字體]
#---------------------------------------
# 字體:可設定Font對象『Font.new('字體名稱', 大小)』或nil使用預設字體
#=======================================
$Sword ? $Sword[18] = [:中文輸入法, 0] : $Sword = {18=>[:中文輸入法, 0]}
end
#=======================================
#■ 注音輸入框
class WSword_Phonetic < Window_Base
attr_accessor(:phonetic) # 已輸入注音內容
attr_accessor(:win_choose) # 關連選字窗口
attr_accessor(:alter) # 修改標誌
# 注音表
Phonetic = {
49=>'ㄅ', 81=>'ㄆ', 65=>'ㄇ', 90=>'ㄈ', 50=>'ㄉ', 87=>'ㄊ', 83=>'ㄋ', 88=>'ㄌ',
69=>'ㄍ', 68=>'ㄎ', 67=>'ㄏ', 82=>'ㄐ', 70=>'ㄑ', 86=>'ㄒ', 53=>'ㄓ', 84=>'ㄔ',
71=>'ㄕ', 66=>'ㄖ', 89=>'ㄗ', 72=>'ㄘ', 78=>'ㄙ', 85=>'ㄧ', 74=>'ㄨ', 77=>'ㄩ',
56=>'ㄚ', 73=>'ㄛ', 75=>'ㄜ', 188=>'ㄝ', 57=>'ㄞ', 79=>'ㄟ', 76=>'ㄠ', 190=>'ㄡ',
48=>'ㄢ', 80=>'ㄣ', 186=>'ㄤ', 191=>'ㄥ', 189=>'ㄦ', 32=>' ', 54=>'ˊ', 51=>'ˇ',
52=>'ˋ', 55=>'˙'}
#------------------------------------------------------
#● 初始化
def initialize
super(16, 16, 64, 64)
self.contents = Bitmap.new(1, 1)
@phonetics = ['', '', '', ''] # [前, 中, 後, 聲]
@phonetic = ''
@alter = false # 修改標誌
@font = Sword::S84_Phonetic[0] ? Sword::S84_Phonetic[0].clone : Font.new
self.visible, self.z = false, 300
end
#------------------------------------------------------
#● 更新內容
def refresh
phonetics = @phonetic.scan(/./) # 分解字串
return self.visible = false if phonetics.empty? # 沒輸入就不顯示
size = @font.size # 獲取字體大小
self.visible = true
if Sword::S84_Horizontal # 橫式
self.width = contents.text_size(@phonetic).width + 32
self.height = size + 32
self.contents = Bitmap.new(width - 32, height - 32)
contents.font = @font
contents.draw_text(0, 0, width - 32, size, @phonetic)
else # 直式
self.width = size + 32
self.height = phonetics.size * size + 32
self.contents = Bitmap.new(width - 32, height - 32)
contents.font = @font
phonetics.each_index{|i| contents.draw_text(0, size * i, size, size, phonetics[i])}
end
end
#------------------------------------------------------
#● 添加(注音鍵值)
def add(key)
return if @win_choose.visible # 選字窗口顯示時不可變更
@alter = false
case key
when 49,81,65,90,50,87,83,88,69,68,67,82,70,86,53,84,71,66,89,72,78 then @phonetics[3], a = '', 0 # 前
when 85,74,77 then @phonetics[3], a = '', 1 # 中
when 56,73,75,188,57,79,76,190,48,80,186,191,189 then @phonetics[3], a = '', 2 # 後
when 32,54,51,52,55 then a = 3 # 聲
else return # 非合理內容
end
@phonetics[a] = Phonetic[key]
@phonetic = @phonetics.to_s
refresh
if a == 3 # 活化選字窗口
@win_choose.refresh(@phonetic)
end
end
#------------------------------------------------------
#● 指定注音(注音)
def set(phonetic)
@alter = true
@phonetic = phonetic
refresh
@win_choose.refresh(@phonetic, true)
end
#------------------------------------------------------
#● 清除(全部清除)
def remove(whole = false)
if whole # 全部清除
@phonetics = ['', '', '', '']
else # 尾字清除
[3, 2, 1, 0].each{|i| (@phonetics[i] = '' ; break) unless @phonetics[i].empty?}
end
@phonetic = @phonetics.to_s
refresh
@win_choose.visible = false
end
end
#=======================================
#■ 選字窗口
class WSword_ChooseWord < Window_Selectable
attr_accessor(:direct) # 直接輸入的字
#------------------------------------------------------
#● 初始化
def initialize
@font = Sword::S84_Choose[2] ? Sword::S84_Choose[2].clone : Font.new
super(0, 0, Sword::S84_Choose[0], (@font.size + Sword::S84_Choose[1]) * 11 + 32)
self.contents = Bitmap.new(width - 32, height - 32)
contents.font = @font
@page = 0 # 頁數
@key = '' # 當前輸入注音
@direct = nil # 無需選字時要直接輸出的字(只有1個字時才用)
self.visible, self.z = false, 300
@chinese = Chinese rescue raise('找不到字庫,請檢查是否有已經放置字庫腳本') # 讀取字庫
end
#------------------------------------------------------
#● 更新內容(注音, 修改標誌)
def refresh(phonetic = nil, alter = false)
if phonetic # 讀取新資料
return RM.se_buzzer unless @chinese[phonetic] # 資料庫未找到該注音的資料時
return @direct = @chinese[phonetic][0] if @chinese[phonetic].size == 1 && ! alter # 直接輸入
@key = phonetic
@page = 0
@index = 0
self.visible = true
end
contents.clear
i = 0
size = @font.size
w = (Sword::S84_Choose[0] - 32) / 2
sa = Sword::S84_Choose[1] + size
# 開始描繪每個選項的字
@chinese[@key][@page * 10, 10].each do |c|
contents.draw_text(0, i * sa, w, sa, (i == 9 ? 0 : i + 1).to_s, 1)
contents.draw_text(w, i * sa, w, sa, c, 1)
i += 1
end
@item_max = i
@page_size = @chinese[@key].size / 10 - (@chinese[@key].size % 10 == 0 ? 1 : 0) # 頁數上限
contents.draw_text(0, height - 32 - size, width - 32, size, "#{@page + 1}/#{@page_size + 1}", 1)
end
#------------------------------------------------------
#● 更新游標
def update_cursor_rect
cursor_rect.set(0, (Sword::S84_Choose[1] + @font.size) *
@index, width - 32, Sword::S84_Choose[1] + @font.size)
end
def update_cursor
update_cursor_rect
end
#------------------------------------------------------
#● 更新
def update
super
choose = nil # 代表確定選擇的項目
if Input.trigger?(37) # 左一頁
@page -= 1
@page = @page_size if @page < 0
refresh
@index = @item_max - 1 if @index >= @item_max # 換頁時游標位置修正
RM.se_cursor
elsif Input.trigger?(39) # 右一頁
@page += 1
@page = 0 if @page > @page_size
refresh
@index = @item_max - 1 if @index >= @item_max
RM.se_cursor
elsif Input.trigger?([13, 32]) # 確定(空白、ENTER)
choose = @index
end
(48..57).each{|i| choose = i == 48 ? 9 : i - 49 if Input.trigger?(i)} unless choose # 左數字鍵
(96..105).each{|i| choose = i == 96 ? 9 : i - 97 if Input.trigger?(i)} unless choose # 右數字鍵
if choose # 確認選擇
return nil unless c = @chinese[@key][@page * 10, 10][choose] # 結果確認
self.visible = false
return c # 返回結果
end
nil # 尚未選字代表的返回值
end
end
#=======================================
#■ 輸入法窗口
class Input_Method
attr_reader(:x) # X座標
attr_reader(:y) # Y座標
attr_reader(:z) # Z座標
attr_reader(:index) # 索引
attr_reader(:row) # 行數
attr_reader(:visible) # 隱藏狀態
attr_reader(:win_seat) # 窗口位置類型
attr_reader(:windowskin) # 窗口皮膚
attr_accessor(:cipher) # 密碼
attr_accessor(:font) # 字體
attr_accessor(:imports) # 當前輸入的內容
attr_accessor(:row_spacing) # 行距
Kind_Max = 2 # 輸入法數量
Phonetic_keys = WSword_Phonetic::Phonetic.keys
# 符號資料庫(左方鍵盤用)
Tilde = { # 半形
48=>')', 49=>'!', 50=>'@', 51=>'#', 52=>'$', 53=>'%', 54=>'^', 55=>'&', 56=>'*', 57=>'(',
186=>':', 187=>'+', 188=>'<', 189=>'_', 190=>'>', 191=>'?', 192=>'~', 219=>'{', 220=>'|', 221=>'}', 222=>'"'}
TILDE = { # 全形
48=>')', 49=>'!', 50=>'@', 51=>'#', 52=>'$', 53=>'%', 54=>'︿', 55=>'&', 56=>'*', 57=>'(',
186=>':', 187=>'+', 188=>'<', 189=>'_', 190=>'>', 191=>'?', 192=>'~', 219=>'{', 220=>'|', 221=>'}', 222=>'"'}
Tilde_keys = Tilde.keys
# 符號資料庫(右方鍵盤用+空白鍵)
TildeR = { # 半形
32=>' ', 96=>'0', 97=>'1', 98=>'2', 99=>'3', 100=>'4', 101=>'5', 102=>'6',
103=>'7', 104=>'8', 105=>'9', 106=>'*', 107=>'+', 109=>'-', 110=>'.', 111=>'/'}
TILDER = { # 全形
32=>' ', 96=>'0', 97=>'1', 98=>'2', 99=>'3', 100=>'4', 101=>'5', 102=>'6',
103=>'7', 104=>'8', 105=>'9', 106=>'*', 107=>'+', 109=>'-', 110=>'。', 111=>'/'}
TildeR_keys = TildeR.keys
# 中文聲符
Pho_Voice = {32=>' ', 54=>'ˊ', 51=>'ˇ', 52=>'ˋ', 55=>'˙'}
# 英文大寫資料庫(半)
English = {
65=>'A', 66=>'B', 67=>'C', 68=>'D', 69=>'E', 70=>'F', 71=>'G', 72=>'H' ,73=>'I',
74=>'J', 75=>'K', 76=>'L', 77=>'M', 78=>'N', 79=>'O', 80=>'P', 81=>'Q' ,82=>'R',
83=>'S', 84=>'T', 85=>'U', 86=>'V', 87=>'W', 88=>'X', 89=>'Y', 90=>'Z', 48=>'0',
49=>'1', 50=>'2', 51=>'3', 52=>'4', 53=>'5', 54=>'6', 55=>'7', 56=>'8', 57=>'9',
191=>'/', 186=>';', 187=>'=', 188=>',', 189=>'-', 190=>'.', 191=>'/', 192=>'`',
219=>'[', 220=>'\\', 221=>']', 222=>'\''}
English_keys = English.keys
# 英文小寫資料庫(半)
English_small = {
65=>'a', 66=>'b', 67=>'c', 68=>'d', 69=>'e', 70=>'f', 71=>'g', 72=>'h' ,73=>'i',
74=>'j', 75=>'k', 76=>'l', 77=>'m', 78=>'n', 79=>'o', 80=>'p', 81=>'q' ,82=>'r',
83=>'s', 84=>'t', 85=>'u', 86=>'v', 87=>'w', 88=>'x', 89=>'y', 90=>'z', 48=>'0',
49=>'1', 50=>'2', 51=>'3', 52=>'4', 53=>'5', 54=>'6', 55=>'7', 56=>'8', 57=>'9',
191=>'/', 186=>';', 187=>'=', 188=>',', 189=>'-', 190=>'.', 191=>'/', 192=>'`',
219=>'[', 220=>'\\', 221=>']', 222=>'\''}
# 英文大寫資料庫(全)
ENGLISH = {
65=>'A', 66=>'B', 67=>'C', 68=>'D', 69=>'E', 70=>'F', 71=>'G', 72=>'H' ,
73=>'I', 74=>'J', 75=>'K', 76=>'L', 77=>'M', 78=>'N', 79=>'O', 80=>'P',
81=>'Q', 82=>'R', 83=>'S', 84=>'T', 85=>'U', 86=>'V', 87=>'W', 88=>'X',
89=>'Y', 90=>'Z', 48=>'0', 49=>'1', 50=>'2', 51=>'3', 52=>'4', 53=>'5',
54=>'6', 55=>'7', 56=>'8', 57=>'9', 186=>';', 187=>'=', 188=>',',
189=>'-', 190=>'。', 191=>'/', 192=>'‵', 219=>'[', 220=>'\', 221=>']', 222=>'’'}
# 英文小寫資料庫(全)
ENGLISH_SMALL = {
65=>'a', 66=>'b', 67=>'c', 68=>'d', 69=>'e', 70=>'f', 71=>'g', 72=>'h' ,
73=>'i', 74=>'j', 75=>'k', 76=>'l', 77=>'m', 78=>'n', 79=>'o', 80=>'p',
81=>'q', 82=>'r', 83=>'s', 84=>'t', 85=>'u', 86=>'v', 87=>'w', 88=>'x',
89=>'y', 90=>'z', 48=>'0', 49=>'1', 50=>'2', 51=>'3', 52=>'4', 53=>'5',
54=>'6', 55=>'7', 56=>'8', 57=>'9', 186=>';', 187=>'=', 188=>',',
189=>'-', 190=>'。', 191=>'/', 192=>'‵', 219=>'[', 220=>'\', 221=>']', 222=>'’',}
@@caps_lock = @@fully = false # 大寫標誌, 全形標誌
@@fully_true = false # 全形標誌變更標誌
@@kind, @@lock = 0, [] # 輸入法種類, 鎖定的輸入法種類
@@win_method_statu = nil # 輸入法狀態窗口
@@manage = {} # 已生成文字輸入框列表
@@active = nil # 正在活動對象
@@win_choose = @@win_phonetic = nil # 選字窗口, 注音輸入框
#------------------------------------------------------
#● 初始化(字數限制, 行數限制, 視口)
def initialize(max = 0, row_max = 0, viewport = nil)
if @@manage.empty? # 未存在文字輸入窗時就生成
@@win_choose = WSword_ChooseWord.new # 選字窗口
@@win_phonetic = WSword_Phonetic.new # 注音輸入框
@@win_phonetic.win_choose = @@win_choose # 關連
end
@@manage[self.__id__] = self # 加入列表
@viewport = viewport # 視口
@font = Sword::S84_Default[0] ? Sword::S84_Default[0].clone : Font.new # 字體
@cipher = '' # 密碼符號
@imports = [[]] # 每行當前輸入的單個文字
@show = [[]] # 用於顯示於文字輸入框的文字
@index = @row = @row_spacing = 0 # 索引、行數、行距
@insert = Sword::S84_Cursor[0] # 文字游標類型
@max = max # 字數限制
@row_max = row_max # 最大行數
@win_seat = Sword::S84_Default[1] # 窗口位置類型
@cursor_size = [0, 0] # 文字游標 [寬度, 高度]
@avail = [] # 按鍵無效列表 [Enter, 聲符(包含右邊小鍵盤), 空白]
@affirm = [0, 0, [], 0, 0] # 等待確認輸入 [X座標, Y座標, 注音, 起始, 終點]
@windowskin = nil # 窗口皮膚
@spr_import = Sprite.new(@viewport) # 輸入窗口
@spr_import.bitmap = Bitmap.new(1, 1) # 一開始計算單個字寬度用的位圖
@spr_cursor = Sprite.new(@viewport) # 文字游標
@spr_cursor.bitmap = Bitmap.new(50, 50)
@cursor_update = 0 # 文字游標的閃爍計數
self.x, self.y, self.z = 0, 0, 200
self.active = @@active.nil? # 活動對象(第1個文字輸入框有效)
@visible = true # 顯示狀態
end
#------------------------------------------------------
#● 獲取文字
def text
text = ''
@imports.each{|import| text += import.to_s + "\n"}
text[-1] = ''
text
end
#------------------------------------------------------
#● 修改文字=(新文字)
def text=(text)
@imports = [[]] # 清空
i = 0
text.split(/\n/).each do |item|
@imports[i] = item.scan(/./)
i += 1
end
refresh
cursor_refresh
end
#------------------------------------------------------
#● 獲取已輸入內容的寬度
def width
return @cursor_size[0] if @spr_import.bitmap.width == 1 # 沒有文字就返回0
@spr_import.bitmap.width + (self.index == @imports[@row].size ? @cursor_size[0] : 0)
end
#------------------------------------------------------
#● 獲取已輸入內容的高度
def height
@spr_import.bitmap.height + (@imports[@row + 1] ? 0 : @cursor_size[1])
end
#------------------------------------------------------
#● 設定X座標=(新X座標)
def x=(x)
@spr_import.x = @x = x
@spr_cursor.x = x + @spr_import.bitmap.text_size(@imports[@row][0, @index].to_s).width
win_phonetic_seat
end
#------------------------------------------------------
#● 設定Y座標=(新Y座標)
def y=(y)
@spr_import.y = @y = y
@spr_cursor.y = y + @row * (@font.size + @row_spacing)
win_phonetic_seat
end
#------------------------------------------------------
#● 設定Z座標=(新Z座標)
def z=(z)
@spr_import.z = @spr_cursor.z = @z = z
end
#------------------------------------------------------
#● 變更索引=(新索引)
def index=(index)
if @affirm[2].empty?
@index = [[index, @imports[@row].size].min, 0].max
else @index = [[index, @affirm[4] + 1].min, @affirm[3]].max
end
cursor_refresh
end
#------------------------------------------------------
#● 獲取活動狀態
def active
equal?(@@active) ? true : false
end
#------------------------------------------------------
#● 變更窗口位置類型
def win_seat=(win_seat)
@win_seat = win_seat
win_phonetic_seat
end
#------------------------------------------------------
#● 變更活動狀態=(活動標誌)
def active=(active)
@spr_cursor.visible = active
if active && ! self.active # 不處於活動狀態的輸入框設為true
if @@active # 如果有其他的文字輸入框活動的情況
@@win_phonetic.remove(true)
@@win_choose.visible = false
@@active.decision
@@active.active = false
end
@@active = self
@spr_cursor.visible = true
cursor_refresh
elsif ! active && self.active # 處於活動狀態的輸入框設為false
@@active = nil
end
end
#------------------------------------------------------
#● 隱藏狀態變更=(隱藏標誌)
def visible=(visible)
@spr_cursor.visible = @spr_import.visible = @visible = visible
end
#------------------------------------------------------
#● 變更行數=(新行數)
def row=(row)
@row = [row, 0].max
@row = [@row, @row_max - 1].min if @row_max > 0
cursor_refresh
end
#------------------------------------------------------
#● 可以輸入判斷(準備添加的字)
def import?(c = '')
return true if @max == 0 # 無限制的場合
if @max > 0 # 字數
n = -1 # 字數計數
@imports.each{|imports| n += 1 ; n += imports.size}
n += 1 unless c.empty?
else ; n = (text + c).size # 字元數
end
return @max.abs >= n # 返回結果
end
#------------------------------------------------------
#● 可以換行判斷
def row?
return true if @row_max <= 0 # 無限制的場合
return @row_max > @imports.size # 返回結果
end
#------------------------------------------------------
#● 到達底行時,Enter是否可用
def enter?
return false if ! @affirm[2].empty? || @@win_phonetic.visible || ! active
row? ? false : (@avail[0] ? false : true)
end
#------------------------------------------------------
#● 更新內容
def refresh
# 計算所需資料
imports, width = [], 0 # 已轉換字串文字列表, 最大寬度
@show = [[]] # 清空
@imports.each_index do |i|
@show[i] = @cipher[0] ? Array.new(@imports[i].size, @cipher) : @imports[i] # 轉密碼
import = @show[i].to_s # 轉換為字串
if a = @spr_import.bitmap.text_size(import).width # 獲取這個字的寬度
width = a if a > width # 設定最大寬度
end
imports << import
end
# 描繪文字內容
width = 1 if width == 0 # 沒有文字的情況下
row = @font.size + @row_spacing # 行距計算
@spr_import.bitmap = Bitmap.new(width, row * @show.size) # 重新產生位圖
@spr_import.bitmap.font = @font
imports.each_index{|i| import = imports[i]
@spr_import.bitmap.draw_text(0, row * i, width, @font.size, import)}
# 描繪待確認文字虛線
unless @affirm[2].empty?
width = @spr_import.bitmap.text_size(@show[@row][@affirm[3]..@affirm[4]].to_s).width
x = 0
while x < width
@spr_import.bitmap.fill_rect(@affirm[0] + x, @affirm[1] + @font.size - 1, 2, 1, @font.color)
x += 3
end
end
cursor_refresh
win_phonetic_seat
end
#------------------------------------------------------
#● 更新文字游標內容
def cursor_refresh
@cursor_update = 0
return unless @spr_cursor.visible = active && visible # 移動文字游標時的顯示
@spr_cursor.x = @x + @spr_import.bitmap.text_size(@show[@row][0, @index].to_s).width
@spr_cursor.y = @y + @row * (@font.size + @row_spacing)
@spr_cursor.bitmap.clear
@spr_cursor.bitmap.font = @font
case @insert
when 0 # |
@spr_cursor.bitmap.fill_rect(0, 0, Sword::S84_Cursor[1], @font.size, @font.color)
@cursor_size = [Sword::S84_Cursor[1], 0]
when 1 # _
width = @spr_cursor.bitmap.text_size(@show[@row][@index] ? @show[@row][@index] : ' ').width
@spr_cursor.bitmap.fill_rect(0, @font.size, width, Sword::S84_Cursor[1], @font.color)
@cursor_size = [width, Sword::S84_Cursor[1]]
end
end
#------------------------------------------------------
#● 更新窗口
def update
return unless active # 不活動就中斷
#○ 文字游標閃爍更新
if @visible # 文字輸入框顯示時
@cursor_update += 1 # 增加游標閃爍計數
@spr_cursor.visible = ! @spr_cursor.visible if @cursor_update % 20 == 0
end
#○ 任何時機均可執行處
Input_Method.update # 輸入法按鍵判斷
if Input.trigger?(45) && Sword::S84_Cursor[2] # 切換文字游標樣式
@insert = @insert == 0 ? 1 : 0
cursor_refresh
elsif Input.press?(16) && Input.trigger?(32) # 切換全半形(追加處理)
@avail[2] = true # 封鎖空白的使用權
end
#○ 注音輸入法相關
if @@win_choose.direct # 當選字窗口只有1個字可選時直接輸入
@avail[1] = true # 封鎖聲符的使用權
add(@@win_choose.direct)
@@win_phonetic.remove(true)
@@win_choose.direct = nil
return
elsif @@win_choose.visible # 選字窗口顯示時
@avail[1] = true # 封鎖聲符的使用權
if c = @@win_choose.update # 更新結果為已經選擇文字時
add(c)
@@win_phonetic.remove(true)
@avail[0] = true # 封鎖Enter的使用權
end
if Input.repeat?(8) then @@win_phonetic.remove # 清除一個注音
elsif Input.trigger?(27) then @@win_phonetic.remove(true) # 清除所有注音
end
return
elsif @@win_phonetic.visible # 注音輸入框顯示時
if Input_Method.kind != 0 # 非注音輸入法時
@@win_phonetic.remove(true)
@@win_choose.visible = false
return
end
Phonetic_keys.each do |key| if Input.trigger?(key) # 注音輸入
@@win_phonetic.add(key)
win_phonetic_seat
end end
if Input.repeat?(8) then @@win_phonetic.remove # 清除一個注音
elsif Input.trigger?(27) then @@win_phonetic.remove(true) # 清除所有注音
end
return
end
#○ 恢復被限制的使用權
@avail[0] = false unless Input.press?(13) if @avail[0] # 恢復Enter使用權
@avail[1] = false if Input.press?(Pho_Voice.keys + TildeR_keys, true).empty? if @avail[1] # 恢復聲符使用權
@avail[2] = false unless Input.press?(16) if @avail[2] # 恢復空白使用權
#○ 等待確認文字處理
unless @affirm[2].empty?
if Input.trigger?(40) # 重新開啟選字窗口
return if @index == @affirm[4] + 1 || @affirm[2][@index - @affirm[3]] == true
win_phonetic_seat
@@win_phonetic.set(@affirm[2][@index - @affirm[3]])
elsif Input.trigger?(13) # 確認結果
@avail[0] = true # 封鎖Enter使用權
return decision
end
end
#○ 不再注音輸入顯現時的按鍵執行
case
when Input.repeat?(8) then remove # 清除前一個字
when Input.repeat?(46) then remove(true) # 清除後一個字
when Input.trigger?(27) then self.text = '' # 清空
when Input.repeat?(37) # 左移
return if @index == @affirm[3] unless @affirm[2].empty?
if @row > 0 && self.index == 0
@row -= 1 ; self.index = @imports[@row].size
else ; self.index -= 1
end
when Input.repeat?(39) # 右移
return if @index == @affirm[4] + 1 unless @affirm[2].empty?
if @imports[@row + 1] && self.index == @imports[@row].size
@row += 1 ; self.index = 0
else ; self.index += 1
end
when Input.repeat?(38) # 上移
return unless @affirm[2].empty?
self.row -= 1 if @row > 0
when Input.repeat?(40) # 下移
return unless @affirm[2].empty?
self.row += 1 if @imports[@row + 1]
when Input.repeat?(13) && ! @avail[0] # 換行
return unless @affirm[2].empty? # 待確認內容情況
return if ! import?("\n") || ! row? # 已達限制就中斷
a = @imports[@row][@index..@imports[@row].size-1] # 獲取換到下行的文字
@imports[@row].slice!(@index..@imports[@row].size-1) # 剪下?!
@row += 1
@imports[@row, 0] = [a] # 貼上?!
refresh
self.index = 0 # 文字游標移動行頭
end
#○ 處理各個輸入法都可用的符號輸入(空白鍵和右方數字鍵)
TildeR_keys.each{|key| add(Input_Method.fully ? TILDER[key] : TildeR[key]) if Input.repeat?(key)} unless @avail[1]
#○ 各類輸入法的處理
case Input_Method.kind
when 0 # 注音輸入
if Input.press?(192) # 按下~在按下符號鍵視同輸入全形符號
Tilde_keys.each{|key| next if key == 192
add(Input.press?(16) ? TILDE[key] : ENGLISH[key]) if Input.trigger?(key)}
return
elsif Input.press?(16) then return english_import # 按下Shift視同英打
end
Pho_Voice.each do |key, value| # 聲符輸入開始
add(value) if Input.repeat?(key) && key != 32 # 輸入聲符
return if Input.press?(key) # 按住期間不可輸入注音
end unless @avail[1]
Phonetic_keys.each do |key| if Input.trigger?(key) # 注音輸入開始
@@win_phonetic.add(key)
win_phonetic_seat
end end
when 1 # 英文輸入
english_import # 英文輸入開始
end
end
#------------------------------------------------------
#● 英文輸入處理
def english_import
fully, caps_lock = Input_Method.fully, Input_Method.caps_lock
English_keys.each do |key| if Input.repeat?(key)
press = Input.press?(16) # Shift按下確認
case
when fully && TILDE[key] && press then add(TILDE[key]) # 全形符號
when Tilde[key] && press then add(Tilde[key]) # 半形符號
when fully && caps_lock != press then add(ENGLISH[key]) # 全形大寫
when fully && ! caps_lock != press then add(ENGLISH_SMALL[key]) # 全形小寫
when caps_lock != press then add(English[key]) # 半形大寫
when ! caps_lock != press then add(English_small[key]) # 半形小寫
end
end end
end
#------------------------------------------------------
#● 添加字到文字輸入框(添加的字)
def add(c)
return if /[ ]/ === c if @avail[2] # 空白輸入封鎖時中斷
# 修改的場合
if @@win_phonetic.alter
@@win_phonetic.alter = false
@imports[@row][@index, 1] = c
self.index += 1
return refresh
end
return unless import?(c) # 突破限制字數就中斷
# 是否可選字判斷
if Sword::S84_Decision
case
when buffer = Choose[c] # 符號
when buffer = @@win_phonetic.phonetic.empty? ? nil : @@win_phonetic.phonetic # 注音
when @affirm[2].size > 0 then buffer = true # 處理
end
# 待確認文字處理
if buffer
if @affirm[2].empty? # 尚未存在待輸入內容時
# 紀錄文字游標X座標, Y座標, 最小索引位置, 最大索引位置
@affirm[0], @affirm[1], @affirm[3], @affirm[4] =
@spr_cursor.x - @x, @spr_cursor.y - @y, @index, @index - 1
end
@affirm[2] << buffer
@affirm[4] += 1 # 最大索引增加
end
end
# 直接輸出
@imports[@row][@index, 0] = c
refresh
self.index += 1
end
#------------------------------------------------------
#● 清除(delete鍵標誌)
def remove(delete = false)
if delete # delete鍵
unless @affirm[2].empty? # 只能刪除待確認文字
return if @index == @affirm[4] + 1 # 游標在待確認文字最左邊就中斷
@affirm[2].delete_at(@index - @affirm[3])
@affirm[4] -= 1
end
@imports[@row].delete_at(@index)
cursor_refresh # 純粹更新文字游標用
else # BACKSPACE鍵
unless @affirm[2].empty? # 只能刪除待確認文字
return if @index == @affirm[3] # 游標在待確認文字最左邊就中斷
@affirm[2].delete_at(@index - @affirm[3] - 1)
@affirm[4] -= 1
end
if @index > 0 # 文字游標非在最左邊時
@imports[@row].delete_at(@index - 1)
self.index -= 1
else # 文字游標在最左邊時
if @row > 0 # 在第2行以上的場合
a = @imports[@row] # 獲取要移動到上一行的字
@imports.delete_at(@row) # 剪下?!
@row -= 1
@imports[@row] += a # 貼上?!
self.index = @imports[@row].size - a.size # 文字游標移至最右邊
end
end
end
refresh
end
#------------------------------------------------------
#● 確認
def decision
@affirm[2].clear
refresh
end
#------------------------------------------------------
#● 設定注音輸入框的位置(類型索引)
def win_phonetic_seat(type = nil)
pho, cho = @@win_phonetic, @@win_choose # 縮短名稱
pho.x = [[@spr_cursor.x + Sword::S84_Phonetic[1], RM.width - pho.width].min, 0].max
pho.y = [[@spr_cursor.y + Sword::S84_Phonetic[2] + @font.size, RM.height - pho.height].min, 0].max
case type ? type : @win_seat
when 1 # 左側下方
cho.x = pho.x - cho.width
return win_phonetic_seat(3) if cho.x < 0
cho.y = [pho.y, RM.height - cho.height].min
when 2 # 下方
cho.y = pho.y + pho.height
return win_phonetic_seat(8) if cho.y + cho.height > RM.height
cho.x = [pho.x, RM.width - pho.width].min
when 3 # 右側下方
cho.x = pho.x + pho.width
return win_phonetic_seat(1) if cho.x + cho.width > RM.width
cho.y = [pho.y, RM.height - cho.height].min
when 7 # 左側上方
cho.x = pho.x - cho.width
return win_phonetic_seat(9) if cho.x < 0
cho.y = [pho.y - cho.height + pho.height, 0].max
when 8 # 上方
cho.y = pho.y - cho.height
return win_phonetic_seat(2) if cho.y < 0
cho.x = [pho.x, RM.width - pho.width].min
when 9 # 右側上方
cho.x = pho.x + pho.width
return win_phonetic_seat(7) if cho.x + cho.width > RM.width
cho.y = [pho.y - cho.height + pho.height, 0].max
end
end
#------------------------------------------------------
#● 釋放窗口
def dispose
@spr_import.dispose
@spr_cursor.dispose
if active # 如果釋放對象為活動窗口時
@@active = nil
if @@win_phonetic.visible # 注音輸入框如果顯示,就清除掉
@@win_phonetic.remove(true)
@@win_choose.visible = false
end
end
@@manage.delete(self.__id__) # 清除紀錄
if @@manage.empty? # 文字輸入框清除光就釋放
@@win_phonetic.dispose
@@win_choose.dispose
end
end
#------------------------------------------------------
#● 設置輸入法狀態窗口(X座標, Y座標)
def self.statu(x = nil, y = nil)
@@win_method_statu = WSword_MethodStatu.new unless @@win_method_statu # 生成
@@win_method_statu.x = x if x
@@win_method_statu.y = y if y
@@win_method_statu.refresh
end
#------------------------------------------------------
#● 釋放輸入法狀態窗口
def self.statu_dispose
return unless @@win_method_statu # 已經釋放就中斷
@@win_method_statu.dispose
@@win_method_statu = nil
end
#------------------------------------------------------
#● 獲取輸入法號
def self.kind
@@lock[0] ? @@lock[0] : @@kind
end
#------------------------------------------------------
#● 獲取大寫標誌
def self.caps_lock
@@lock[1].nil? ? @@caps_lock : @@lock[1]
end
#------------------------------------------------------
#● 獲取全形標誌
def self.fully
@@lock[2].nil? ? @@fully : @@lock[2]
end
#------------------------------------------------------
#● 鎖定輸入法(輸入法種類, 大寫標誌, 全型標誌)
def self.lock(kind = nil, caps_lock = nil, fully = nil)
@@lock = [kind, caps_lock, fully]
@@win_method_statu.refresh if @@win_method_statu # 更新輸入法狀態窗口
end
#------------------------------------------------------
#● 更新按鍵
def self.update
if Input.trigger?(20) # 切換大小寫
@@caps_lock = ! @@caps_lock
@@win_method_statu.refresh if @@win_method_statu # 更新輸入法狀態窗口
elsif Input.trigger?(17) # 切換輸入法
@@kind += 1
@@kind = 0 if @@kind == Kind_Max
@@win_method_statu.refresh if @@win_method_statu # 更新輸入法狀態窗口
elsif Input.press?(16) && Input.trigger?(32) # 切換全半形
@@fully = ! @@fully
@@win_method_statu.refresh if @@win_method_statu # 更新輸入法狀態窗口
end
end
end
#=======================================
#■ 輸入法狀態窗口
class WSword_MethodStatu < Window_Base
#------------------------------------------------------
#● 初始化
def initialize
super(0, 0, 96, 64)
self.contents = Bitmap.new(width - 32, height - 32)
end
#------------------------------------------------------
#● 更新內容
def refresh
contents.clear
contents.draw_text(0, 0, 32, 32,
Input_Method.kind == 0 ? 'ㄅ' : (Input_Method.caps_lock ? 'A' : 'a'), 1)
contents.fill_rect(36, 4, 24, 24, contents.font.color)
contents.fill_rect(36 + 12, 5, 11, 22, Color.new(0, 0, 0, 0)) unless Input_Method.fully
end
end
|
|