From f8744e2ec259cdb72c77e6095cf2e7e329ba081d Mon Sep 17 00:00:00 2001 From: Warmist Date: Fri, 31 Aug 2012 23:46:33 +0300 Subject: [PATCH] Experimental stuff editor (can and will crash DF ) --- scripts/gui/gm-Items.lua | 181 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 scripts/gui/gm-Items.lua diff --git a/scripts/gui/gm-Items.lua b/scripts/gui/gm-Items.lua new file mode 100644 index 000000000..82a1da154 --- /dev/null +++ b/scripts/gui/gm-Items.lua @@ -0,0 +1,181 @@ +-- Interface powered item editor. +-- TODO use this: MechanismList = defclass(MechanismList, guidm.MenuOverlay) +local gui = require 'gui' + +if dfhack.gui.getCurFocus() ~= 'item' then + qerror("This script requires the item view.") +end + +TextInputDialog = defclass(TextInputDialog, gui.FramedScreen) + +function TextInputDialog:init(prompt) + self.frame_style=GREY_LINE_FRAME + self.frame_title=prompt + self.input="" + return self +end +function TextInputDialog:onRenderBody(dc) + dc:seek(1,1):string(self.input, COLOR_WHITE):newline() +end + +local MODE_BROWSE=0 +local MODE_EDIT=1 +local item_screen={ + frame_style = gui.GREY_LINE_FRAME, + frame_title = "GameMaster's editor", + stack={}, + item_count=0, + mode=MODE_BROWSE, + + keys={}, + insertNew=function(self) + --[=[local trg=self:currentTarget() -- not sure if possible... + if trg.target and trg.target._kind and trg.target._kind=="container" then + local thing=df.new('general_ref_contained_itemst') + trg.target:insert('#',trg.keys[trg.selected]) + end]=] + end, + deleteSelected=function(self) + local trg=self:currentTarget() + if trg.target and trg.target._kind and trg.target._kind=="container" then + trg.target:erase(trg.keys[trg.selected]) + end + end, + currentTarget=function(self) + return self.stack[#self.stack] + end, + changeSelected = function (self,delta) + local trg=self:currentTarget() + if trg.item_count <= 1 then return end + trg.selected = 1 + (trg.selected + delta - 1) % trg.item_count + end, + editSelected = function(self) + local trg=self:currentTarget() + if trg.target and trg.target._kind and trg.target._kind=="bitfield" then + trg.target[trg.keys[trg.selected]]= not trg.target[trg.keys[trg.selected]] + else + --print(type(trg.target[trg.keys[trg.selected]]),trg.target[trg.keys[trg.selected]]._kind or "") + local trg_type=type(trg.target[trg.keys[trg.selected]]) + if trg_type=='number' or trg_type=='string' then --ugly TODO: add metatable get selected + self.mode=MODE_EDIT + self.input=tostring(trg.target[trg.keys[trg.selected]]) + elseif trg_type=='userdata' then + self:pushTarget(trg.target[trg.keys[trg.selected]]) + --local screen = mkinstance(gui.FramedScreen,item_screen):init(trg.target[trg.keys[trg.selected]]) -- does not work + --screen:show() + else + print("Unknow type:"..trg_type) + print("Subtype:"..tostring(trg.target[trg.keys[trg.selected]]._kind)) + end + end + end, + cancelEdit = function(self) + self.mode=MODE_BROWSE + self.input="" + end, + commitEdit = function(self) + local trg=self:currentTarget() + self.mode=MODE_BROWSE + if type(trg.target[trg.keys[trg.selected]])=='number' then + trg.target[trg.keys[trg.selected]]=tonumber(self.input) + elseif type(trg.target[trg.keys[trg.selected]])=='string' then + trg.target[trg.keys[trg.selected]]=self.input + end + end, + onRenderBody = function(self, dc) + local trg=self:currentTarget() + dc:seek(2,1):string(tostring(trg.target), COLOR_RED) + local offset=2 + local page_offset=0 + local current_item=1 + local t_col + if math.floor(trg.selected / (self.frame_height-offset-2)) >0 then + page_offset=math.floor(trg.selected / (self.frame_height-offset-2))*(self.frame_height-offset-2)-1 + end + for k,v in pairs(trg.target) do + + if current_item==trg.selected then + t_col=COLOR_LIGHTGREEN + else + t_col=COLOR_GRAY + end + + if current_item-page_offset > 0 then + local y_pos=current_item-page_offset+offset + dc:seek(2,y_pos):string(tostring(k),t_col) + + if self.mode==MODE_EDIT and current_item==trg.selected then + dc:seek(20,y_pos):string(self.input..'_',COLOR_GREEN) + else + dc:seek(20,y_pos):string(tostring(v),t_col) + end + end + current_item=current_item+1 + end + end, + + onInput = function(self,keys) + if self.mode==MODE_BROWSE then + if keys.LEAVESCREEN then + self:popTarget() + elseif keys.CURSOR_UP then + self:changeSelected(-1) + elseif keys.CURSOR_DOWN then + self:changeSelected(1) + elseif keys.CURSOR_UP_FAST then + self:changeSelected(-10) + elseif keys.CURSOR_DOWN_FAST then + self:changeSelected(10) + elseif keys.SELECT then + self:editSelected() + elseif keys.CUSTOM_ALT_E then + --self:specialEditor() + local screen = mkinstance(TextInputDialog):init("Input new coordinates") + screen:show() + elseif keys.CUSTOM_ALT_I then --insert + self:insertNew() + elseif keys.CUSTOM_ALT_D then --delete + self:deleteSelected() + end + elseif self.mode==MODE_EDIT then + if keys.LEAVESCREEN then + self:cancelEdit() + elseif keys.SELECT then + self:commitEdit() + elseif keys._STRING then + if keys._STRING==0 then + self.input=string.sub(self.input,1,-2) + else + self.input=self.input.. string.char(keys._STRING) + end + end + end + end, + pushTarget=function(self,target_to_push) + local new_tbl={} + new_tbl.target=target_to_push + new_tbl.keys={} + new_tbl.selected=1 + for k,v in pairs(target_to_push) do + table.insert(new_tbl.keys,k) + end + new_tbl.item_count=#new_tbl.keys + table.insert(self.stack,new_tbl) + end, + popTarget=function(self) + table.remove(self.stack) --removes last element + if #self.stack==0 then + self:dismiss() + end + end, + init = function(self,item_to_edit) + self:pushTarget(item_to_edit) + self.frame_width,self.frame_height=dfhack.screen.getWindowSize() + return self + end + } + + + +local screen = mkinstance(gui.FramedScreen,item_screen):init(dfhack.gui.getCurViewscreen().item) +screen:show() \ No newline at end of file