IUP基礎 - hiz1/lua GitHub Wiki
基礎
Luaファイルの場所に、iup.dll・iuplua53.dllをコピー。
※ package.cpathで別のフォルダ指定してそこにdll置いてもダメっぽい。
Hello, world
package.cpath = package.cpath .. ";.\\?53.dll"
require("iuplua")
iup.Message("Hello World 1","Hello world from IUP.")
-- to be able to run this script inside another context
if (iup.MainLoopLevel()==0) then
iup.MainLoop()
iup.Close()
end
サイズは文字列で指定。"100x20"など。"QUARTERxQUARTER"でスクリーンの縦横4分の1サイズ。
true/falseも文字列で指定。"YES"/"NO"
コントロールの生成は、コンストラクタの後にオブジェクト書く。
button = iup.button{title = "OK", size="40x12"}
コールバックはコンストラクタ引数(action)に関数渡すか、コントロールのメソッド作成。
button = iup.button{title = "OK", size="40x12", action = function(self) return iup.CLOSE end}
function button:action()
-- Exits the main loop
return iup.CLOSE
end
バッチファイル実行
以下のようなバッチファイルを用意。
@echo off
D:
cd D:\Develop\lua\iup\test001
lua53 main.lua %1
バッチファイルのショートカットを作成し、実行時の大きさを「最小化」に設定。
ダイアログ
ファイル選択ダイアログ(保存)呼び出しは、
local filedlg = iup.filedlg{
dialogtype = "SAVE",
filter = "*.txt",
filterinfo = "Text Files",
}
filedlg:popup(iup.CENTER, iup.CENTER)
if (tonumber(filedlg.status) ~= -1) then
-- ファイル選択後の処理(filedlg.valueで選択したファイルパスの取得)
end
filedlg:destroy()
ファイル選択ダイアログ(読み込み)呼び出しは、
local filedlg = iup.filedlg{
dialogtype = "OPEN",
filter = "*.txt",
filterinfo = "Text Files",
}
filedlg:popup(iup.CENTER, iup.CENTER)
if (tonumber(filedlg.status) ~= -1) then
-- ファイル選択後の処理(filedlg.valueで選択したファイルパスの取得)
end
filedlg:destroy()
カスタムダイアログ呼び出しは、
local line_count = multitext.linecount
local lbl_goto = iup.label{title = "Line Number [1-"..line_count.."]:"}
local txt_goto = iup.text{mask = iup.MASK_UINT, visiblecolumns = 20} --unsigned integer numbers only
local bt_goto_ok = iup.button{title = "OK", text_linecount = 0, padding = "10x2"}
bt_goto_ok.text_linecount = line_count
function bt_goto_ok:action()
local line_count = tonumber(self.text_linecount)
local line = tonumber(txt_goto.value)
if (line < 1 or line >= line_count) then
iup.Message("Error", "Invalid line number.")
return
end
goto_dlg.status = 1
return iup.CLOSE
end
local bt_goto_cancel = iup.button{title = "Cancel", padding = "10x2"}
function bt_goto_cancel:action()
goto_dlg.status = 0
return iup.CLOSE
end
local box = iup.vbox{
lbl_goto,
txt_goto,
iup.hbox{
iup.fill{},
bt_goto_ok,
bt_goto_cancel,
normalizesize="HORIZONTAL",
},
margin = "10x10",
gap = "5",
}
goto_dlg = iup.dialog{
box,
title = "Go To Line",
dialogframe = "Yes",
defaultenter = bt_goto_ok,
defaultesc = bt_goto_cancel,
parentdialog = iup.GetDialog(self)
}
goto_dlg:popup(iup.CENTERPARENT, iup.CENTERPARENT)
if (tonumber(goto_dlg.status) == 1) then
-- OKボタン押下後の処理(txt_goto.valueで入力内容取得)
end
goto_dlg:destroy()
ツールバー・ステータスバー
ツールバー・ステータスバ-は特別なコントロールではない。
単純にダイアログの上下に置かれる横幅100%のコントロール。
ツールバー
標準アイコンを使うために、以下のモジュールをrequireする。
require("iupluaimglib")
iupluaimglib53.dll・iupimglib.dllをluaファイルのフォルダにコピー。
btn_open = iup.button{image = "IUP_FileOpen", flat = "Yes", action = item_open.action, canfocus="No", tip = "Open (Ctrl+O)"}
btn_save = iup.button{image = "IUP_FileSave", flat = "Yes", action = item_saveas.action, canfocus="No", tip = "Save (Ctrl+S)"}
btn_find = iup.button{image = "IUP_EditFind", flat = "Yes", action = item_find.action, canfocus="No", tip = "Find (Ctrl+F)"}
toolbar_hb = iup.hbox{
btn_open,
btn_save,
iup.label{separator="VERTICAL"},
btn_find,
margin = "5x5",
gap = 2,
}
vbox = iup.vbox{
toolbar_hb,
multitext
}
dlg = iup.dialog{
vbox,
title = "Simple Notepad",
size = "QUARTERxQUARTER",
menu = menu
}
ステータスバー
lbl_statusbar = iup.label{title = "Lin 1, Col 1", expand = "HORIZONTAL", padding = "10x5"}
vbox = iup.vbox{
toolbar_hb,
multitext,
lbl_statusbar,
}
ホットキー
ショートカットキー
ダイアログのコールバックk_anyを定義。
function dlg:k_any(c)
if (c == iup.K_cO) then
item_open:action()
elseif (c == iup.K_cS) then
item_saveas:action()
elseif (c == iup.K_cF) then
item_find:action()
elseif (c == iup.K_cG) then
item_goto:action()
end
end
ホットキー
ホットキーの直前に&を記述。
item_open = iup.item{title="&Open...\tCtrl+O"}
item_saveas = iup.item{title="Save &As...\tCtrl+S"}
item_font = iup.item{title="&Font (Ctrl+F)"}
item_about = iup.item{title="&About..."}
item_find = iup.item{title="&Find...\tCtrl+F"}
item_goto = iup.item{title="&Go To..."}
item_exit = iup.item{title="E&xit"}
コンフィグファイル
初期化
config = iup.config{}
config.app_name = "simple_notepad"
config:Load()
終了時の保存
function dlg:destroy_cb()
config:DialogClosed(iup.GetDialog(self), "MainWindow")
config:Save()
config:destroy()
end
書き込み
config:SetVariable("MainWindow", "Font", fontdlg.value)
読み込み
config:SetVariable("MainWindow", "Font", fontdlg.value)
最近のファイル一覧更新
config:RecentUpdate(filename)
最近のファイル一覧表示
recent_menu = iup.menu{}
file_menu = iup.menu{
item_open,
item_saveas,
iup.submenu{title="Recent &Files", recent_menu},
iup.separator{},
item_exit
}
config:RecentInit(recent_menu, 10)
選択したファイルの読み込み
function config:recent_cb()
local filename = self.title
local str = read_file(filename)
if (str) then
multitext.value = str
end
end
前回の表示位置・サイズでダイアログ表示
config:DialogShow(dlg, "MainWindow")
クリップボード
クリップボード用メニューアイテム作成
item_copy = iup.item{title="&Copy\tCtrl+C"}
item_paste = iup.item{title="&Paste\tCtrl+V"}
item_cut = iup.item{title="Cu&t\tCtrl+X"}
item_delete = iup.item{title="&Delete\tDel"}
item_select_all = iup.item{title="Select &All\tCtrl+A"}
クリップボード用コールバック作成
function item_paste:action()
local clipboard = iup.clipboard{}
multitext.insert = clipboard.text
clipboard:destroy()
return iup.IGNORE -- avoid system processing for hot keys, to correctly parse line feed
end
function item_cut:action()
local clipboard = iup.clipboard{text = multitext.selectedtext}
multitext.selectedtext = ""
clipboard:destroy()
end
function item_delete:action()
multitext.selectedtext = ""
end
function item_select_all:action()
iup.SetFocus(multitext)
multitext.selection = "ALL"
end
メニュー設定
edit_menu = iup.menu{
item_cut,
item_copy,
item_paste,
item_delete,
iup.separator{},
item_find,
item_goto,
iup.separator{},
item_select_all
}
function edit_menu:open_cb()
local clipboard = iup.clipboard{}
if (not clipboard.textavailable) then
item_paste.active = "NO"
else
item_paste.active = "YES"
end
if (not multitext.selectedtext) then
item_cut.active = "NO"
item_delete.active = "NO"
item_copy.active = "NO"
else
item_cut.active = "YES"
item_delete.active = "YES"
item_copy.active = "YES"
end
clipboard:destroy()
end
ダイナミックレイアウト
ステータスバー・ツールバーの表示・非表示を切り替える場合
※ floatingがNOだと非表示にしてもその場所にスペースが空いてしまう。
function toggle_bar_visibility(item, bar)
if (item.value == "ON") then
bar.floating = "YES"
bar.visible = "NO"
item.value = "OFF"
else
bar.floating = "NO"
bar.visible = "YES"
item.value = "ON"
end
iup.Refresh(bar) -- refresh the dialog layout
end
ファイルドロップ
function multitext:dropfiles_cb(filename)
if (save_check(self)) then
open_file(self, filename)
end
end
dlg = iup.dialog{
vbox,
title = "Simple Notepad",
size = "HALFxHALF",
menu = menu,
multitext = multitext,
dropfiles_cb = multitext.dropfiles_cb,
}
終了時保存チェック
function save_check(ih)
local dlg = iup.GetDialog(ih)
local multitext = dlg.multitext
if (multitext.dirty) then
local resp = iup.Alarm("Warning", "File not saved! Save it now?", "Yes", "No", "Cancel")
if resp == 1 then -- save the changes and continue
save_file(multitext)
elseif resp == 3 then -- cancel
return false
else -- ignore the changes and continue
end
end
return true
end
function multitext:valuechanged_cb()
self.dirty = "YES"
end
function item_exit:action()
if not save_check(self) then
return iup.IGNORE -- to abort the CLOSE_CB callback
end
config:DialogClosed(iup.GetDialog(self), "MainWindow")
config:Save()
config:destroy()
return iup.CLOSE
end
dlg = iup.dialog{
vbox,
title = "Simple Notepad",
size = "HALFxHALF",
menu = menu,
close_cb = item_exit.action
}
#コマンドライン引数
-- open a file from the command line (allow file association in Windows)
if (arg and arg[1]) then
filename = arg[1]
open_file(dlg, filename)
end
外部ヘルプ
function item_help:action()
iup.Help("http://www.tecgraf.puc-rio.br/iup")
end
グラフィック
IMライブラリが別途必要。
ダウンロードリンクからDLLダウンロードできる。
im-3.12-Lua53_Win32_dllw4_lib.zip・im-3.12_Win32_dllw4_lib.zipをダウンロードしてim.dll・imlua53.dll・zlib1.dllをコピーする。
Canvas Drawと一緒に使う場合、v2は完全な互換性がある。v3で一緒に使う場合、 Bitmapしか使えない。
imFileImageLoadBitmapで画像ファイルを読み込むか、imImageをimConvertToBitmapでBitmapに変換する必要あり。
IMは画像編集ソフト作るので無ければimFileImageLoadBitmapだけ使えれば問題なさそう。後はCanvas Drawでなんとかする。
require
require("iuplua")
require("iupluaimglib")
require("imlua")
require("iupluaim")
画像ファイル読み込み
function read_file(filename)
local image, err = im.FileImageLoadBitmap(filename, 0)
if (err) then
show_error(im.ErrorStr(err), true)
else
-- we are going to support only RGB images with no alpha
image:RemoveAlpha()
if (image:ColorSpace() ~= im.RGB) then
local new_image = im.ImageCreateBased(image, nil, nil, im.RGB, nil)
im.ConvertColorSpace(image, new_image)
image:Destroy()
image = new_image
end
end
return image
end
function write_file(filename, image)
local format = image:GetAttribString("FileFormat")
local err = im.FileImageSave(filename, format, image)
if (err and err ~= im.ERR_NONE) then
show_error(im.ErrorStr(err), true)
return false
end
return true
end
画像新規作成
local image = im.ImageCreate(width, height, im.RGB, im.BYTE)
キャンバス作成
config = iup.config{}
config.app_name = "simple_paint"
config:Load()
canvas = iup.canvas{
config = config,
dirty = nil,
}
dlg = iup.dialog{
vbox,
title = "Simple Paint",
size = "HALFxHALF",
canvas = canvas
}
OpenGL
luaGLライブラリが別途必要。
ダウンロードリンクからDLLダウンロード。
iupgl.dll・iupluagl53.dll・luagl.dll・luagl_base.dll・luaglu.dllをコピー。
キャンバス作成
canvas = iup.glcanvas{
config = config,
dirty = nil,
buffer = "DOUBLE",
}
キャンバス描画
function canvas:action()
local image = canvas.image
local canvas_width, canvas_height = string.match(canvas.drawsize,"(%d*)x(%d*)")
canvas:MakeCurrent()
-- OpenGL configuration
gl.PixelStore(gl.UNPACK_ALIGNMENT, 1) -- image data alignment is 1
gl.Viewport(0, 0, canvas_width, canvas_height)
gl.MatrixMode(gl.PROJECTION)
gl.LoadIdentity()
gl.Ortho(0, canvas_width, 0, canvas_height, -1, 1)
gl.MatrixMode(gl.MODELVIEW)
gl.LoadIdentity()
-- draw the background
local background = config:GetVariableDef("Canvas", "Background", "255 255 255")
local r, g, b = string.match(background, "(%d*) (%d*) (%d*)")
gl.ClearColor(r / 255, g / 255, b / 255, 1)
gl.Clear(gl.COLOR_BUFFER_BIT)
-- draw the image at the center of the canvas
if (image) then
local x = (canvas_width - image:Width()) / 2
local y = (canvas_height - image:Height()) / 2
gl.RasterPos(x, y) -- this will not work for negative values, an OpenGL limitation
gl.DrawPixelsRaw(image:Width(), image:Height(), gl.RGB, gl.UNSIGNED_BYTE, canvas.gldata) -- no zoom support, must use texture
end
canvas:SwapBuffers()
end
CD(Canvas Draw)
CDライブラリが別途必要。
ダウンロードリンクからDLLダウンロードできる。
CDのDLL・luacdのDLLを全部コピー、cdim.dll・cdluaim53.dllをコピー。
キャンバス作成
function canvas:map_cb()
cd_canvas = cd.CreateCanvas(cd.IUPDBUFFER, canvas)
canvas.cdCanvas = cd_canvas
end
function canvas:unmap_cb()
local cd_canvas = canvas.cdCanvas
cd_canvas:Kill()
end
canvas = iup.canvas{
config = config,
dirty = nil,
}
キャンバス描画
function canvas:action()
local image = canvas.image
local canvas_width, canvas_height = string.match(canvas.drawsize,"(%d*)x(%d*)")
local cd_canvas = canvas.cdCanvas
cd_canvas:Activate()
-- draw the background
local background = config:GetVariableDef("Canvas", "Background", "255 255 255")
local r, g, b = string.match(background, "(%d*) (%d*) (%d*)")
cd_canvas:Background(cd.EncodeColor(r, g, b))
cd_canvas:Clear()
-- draw the image at the center of the canvas
if (image) then
local x = math.floor((canvas_width - image:Width()) / 2)
local y = math.floor((canvas_height - image:Height()) / 2)
image:cdCanvasPutImageRect(cd_canvas, x, y, image:Width(), image:Height(), 0, 0, 0, 0)
end
cd_canvas:Flush()
end
ツールボックス
function tool_action_cb(ih, state)
if (state == 1) then
local tool_index = tonumber(ih.toolindex)
toolbox.toolindex = tool_index
if (tool_index == 0) then
canvas.cursor = "ARROW"
else
canvas.cursor = "CROSS"
end
if (tool_index == 8) then
tool_get_text()
end
end
end
gbox = iup.gridbox{
iup.toggle{toolindex=0, image=load_image_PaintPointer(), value="ON", flat="Yes", tip="Pointer", action = tool_action_cb},
iup.toggle{toolindex=1, image=load_image_PaintColorPicker(), flat="Yes", tip="Color Picker", action = tool_action_cb},
iup.toggle{toolindex=2, image=load_image_PaintPencil(), flat="Yes", tip="Pencil", action = tool_action_cb},
iup.toggle{toolindex=3, image=load_image_PaintLine(), flat="Yes", tip="Line", action = tool_action_cb},
iup.toggle{toolindex=4, image=load_image_PaintRect(), flat="Yes", tip="Hollow Rectangle", action = tool_action_cb},
iup.toggle{toolindex=5, image=load_image_PaintBox(), flat="Yes", tip="Box (Filled Rectangle)", action = tool_action_cb},
iup.toggle{toolindex=6, image=load_image_PaintEllipse(), flat="Yes", tip="Hollow Ellipse", action = tool_action_cb},
iup.toggle{toolindex=7, image=load_image_PaintOval(), flat="Yes", tip="Oval (Filled Ellipse)", action = tool_action_cb},
iup.toggle{toolindex=8, image=load_image_PaintText(), flat="Yes", tip="Text", action = tool_action_cb},
iup.toggle{toolindex=9, image=load_image_PaintFill(), flat="Yes", tip="Fill Color", action = tool_action_cb},
gapcol = 2,
gaplin = 2,
margin = "5x10",
numdiv = 2
}
vbox = iup.vbox{
iup.radio{gbox},