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