diff --git a/game/engines/default/engine/Dialog.lua b/game/engines/default/engine/Dialog.lua
index dd01da797580d00b163a0e0d50c8e7740451fa2a..df972116ba618ff4d004a862c3d05370a554d70c 100644
--- a/game/engines/default/engine/Dialog.lua
+++ b/game/engines/default/engine/Dialog.lua
@@ -314,16 +314,6 @@ function _M:mouseZones(t, no_new)
 end
 
 function _M:unload()
---[[
-	if self.old_key then
-		game.key = self.old_key
-		game.key:setCurrent()
-	end
-	if self.old_mouse then
-		game.mouse = self.old_mouse
-		game.mouse:setCurrent()
-	end
-]]
 end
 
 function _M:drawWBorder(s, x, y, w)
diff --git a/game/engines/default/engine/dialogs/ShowEquipInven.lua b/game/engines/default/engine/dialogs/ShowEquipInven.lua
index f7f0502db55f7f15201bdeeef48055f2f85a300e..6842d826f1577b4832a5f32f7be2081fb9caccda 100644
--- a/game/engines/default/engine/dialogs/ShowEquipInven.lua
+++ b/game/engines/default/engine/dialogs/ShowEquipInven.lua
@@ -18,32 +18,51 @@
 -- darkgod@te4.org
 
 require "engine.class"
-require "engine.Dialog"
+local Dialog = require "engine.ui.Dialog"
+local ListColumns = require "engine.ui.ListColumns"
+local Textzone = require "engine.ui.Textzone"
 
-module(..., package.seeall, class.inherit(engine.Dialog))
+module(..., package.seeall, class.inherit(Dialog))
 
 function _M:init(title, actor, filter, action)
 	self.action = action
 	self.filter = filter
 	self.actor = actor
 
-	engine.Dialog.init(self, title or "Inventory", game.w * 0.8, game.h * 0.8, nil, nil, nil, core.display.newFont("/data/font/VeraMono.ttf", 12))
+	Dialog.init(self, title or "Inventory", game.w * 0.8, game.h * 0.8)
 
 	self:generateList()
 
-	self.list = self.inven_list
-	self.sel = 1
-	self.scroll = 1
---	self.max = math.floor((self.ih * 0.8 - 5) / self.font_h) - 1
+	self.c_inven = ListColumns.new{width=math.floor(self.iw / 2 - 10), height=self.ih - self.max_h - 10, sortable=true, scrollbar=true, columns={
+		{name="", width=7, display_prop="id", sort="id"},
+		{name="", width=4, display_prop="char", sort="char"},
+		{name="Inventory", width=61, display_prop="name", sort="name"},
+		{name="Category", width=20, display_prop="cat", sort="cat"},
+		{name="Enc.", width=8, display_prop="encumberance", sort="encumberance"},
+	}, list=self.inven_list, fct=function(item, sel) self:use(item) end}
+
+	self.c_equip = ListColumns.new{width=math.floor(self.iw / 2 - 10), height=self.ih - self.max_h - 10, scrollbar=true, columns={
+		{name="", width=4, display_prop="char", sort="char"},
+		{name="Equipment", width=68, display_prop="name"},
+		{name="Category", width=20, display_prop="cat"},
+		{name="Enc.", width=8, display_prop="encumberance"},
+	}, list=self.equip_list, fct=function(item) self:use(item) end}
+
+	self:loadUI{
+		{left=0, top=0, ui=self.c_equip},
+		{right=0, top=0, ui=self.c_inven},
+	}
+
 
-	self:keyCommands({
+	self.key:addCommands{
 		__TEXTINPUT = function(c)
 			if self.list.chars[c] then
 				self.sel = self.list.chars[c]
 				self:use()
 			end
 		end,
-	},{
+	}
+	self.key:addBinds{
 		HOTKEY_1 = function() self:defineHotkey(1) end,
 		HOTKEY_2 = function() self:defineHotkey(2) end,
 		HOTKEY_3 = function() self:defineHotkey(3) end,
@@ -80,47 +99,32 @@ function _M:init(title, actor, filter, action)
 		HOTKEY_THIRD_10 = function() self:defineHotkey(34) end,
 		HOTKEY_THIRD_11 = function() self:defineHotkey(35) end,
 		HOTKEY_THIRD_12 = function() self:defineHotkey(36) end,
-
-		MOVE_UP = function() self.sel = util.boundWrap(self.sel - 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		MOVE_DOWN = function() self.sel = util.boundWrap(self.sel + 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		MOVE_LEFT = function() self.list = self.equip_list self.sel = util.bound(self.sel, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		MOVE_RIGHT = function() self.list = self.inven_list self.sel = util.bound(self.sel, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end,
-		ACCEPT = function() self:use() end,
-		EXIT = function() game:unregisterDialog(self) end,
-	})
-	self:mouseZones{
-		{ x=0, y=0, w=game.w, h=game.h, mode={button=true}, norestrict=true, fct=function(button) if button == "left" then game:unregisterDialog(self) end end},
-		{ x=2, y=5, w=self.iw, h=self.font_h*self.max, fct=function(button, x, y, xrel, yrel, tx, ty, event)
-			if tx < self.iw / 2 then
-				self.list = self.equip_list
-			else
-				self.list = self.inven_list
-			end
-			if button ~= "wheelup" and button ~= "wheeldown" then
-				self.sel = util.bound(self.scroll + math.floor(ty / self.font_h), 1, #self.list)
+		ACCEPT = function()
+			if self.focus_ui and self.focus_ui.ui == self.c_inven then self:use(self.c_inven.list[self.c_inven.sel])
+			elseif self.focus_ui and self.focus_ui.ui == self.c_equip then self:use(self.c_equip.list[self.c_equip.sel])
 			end
-			self.changed = true
-
-			if button == "left" and event == "button" then self:use()
-			elseif button == "right" and event == "button" then
-			elseif button == "wheelup" and event == "button" then self.key:triggerVirtual("MOVE_UP")
-			elseif button == "wheeldown" and event == "button" then self.key:triggerVirtual("MOVE_DOWN")
-			end
-		end },
+		end,
+		EXIT = function() game:unregisterDialog(self) end,
 	}
 end
 
 function _M:defineHotkey(id)
 	if not self.actor or not self.actor.hotkey then return end
 
-	self.actor.hotkey[id] = {"inventory", self.list[self.sel].object:getName{no_count=true}}
-	self:simplePopup("Hotkey "..id.." assigned", self.list[self.sel].object:getName{no_count=true}:capitalize().." assigned to hotkey "..id)
+	local item = nil
+	if self.focus_ui and self.focus_ui.ui == self.c_inven then item = self.c_inven.list[self.c_inven.sel]
+	elseif self.focus_ui and self.focus_ui.ui == self.c_equip then item = self.c_equip.list[self.c_equip.sel]
+	end
+	if not item or not item.object then return end
+
+	self.actor.hotkey[id] = {"inventory", item.object:getName{no_count=true}}
+	self:simplePopup("Hotkey "..id.." assigned", item.object:getName{no_count=true}:capitalize().." assigned to hotkey "..id)
 	self.actor.changed = true
 end
 
-function _M:use()
-	if self.list[self.sel] and self.list[self.sel].item then
-		if self.action(self.list[self.sel].object, self.list[self.sel].inven, self.list[self.sel].item) then
+function _M:use(item)
+	if item then
+		if self.action(item.object, item.inven, item.item) then
 			game:unregisterDialog(self)
 		end
 	end
@@ -128,19 +132,20 @@ end
 
 function _M:generateList()
 	-- Makes up the list
-	local list = {}
+	self.equip_list = {}
+	local list = self.equip_list
 	local chars = {}
 	local i = 0
 	self.max_h = 0
 	for inven_id =  1, #self.actor.inven_def do
 		if self.actor.inven[inven_id] and self.actor.inven_def[inven_id].is_worn then
-			list[#list+1] = { name=self.actor.inven_def[inven_id].name, color={0x90, 0x90, 0x90}, inven=inven_id }
+			list[#list+1] = { id=#list+1, char="", name=self.actor.inven_def[inven_id].name, color={0x90, 0x90, 0x90}, inven=inven_id, cat="", encumberance="" }
 			self.max_h = math.max(self.max_h, #self.actor.inven_def[inven_id].description:splitLines(self.iw - 10, self.font))
 
 			for item, o in ipairs(self.actor.inven[inven_id]) do
 				if not self.filter or self.filter(o) then
 					local char = string.char(string.byte('a') + i)
-					list[#list+1] = { name=char..") "..o:getDisplayString()..o:getName(), color=o:getDisplayColor(), object=o, inven=inven_id, item=item }
+					list[#list+1] = { id=#list+1, char=char, name=o:getDisplayString()..o:getName(), color=o:getDisplayColor(), object=o, inven=inven_id, item=item, cat=o.type.."/"..o.subtype, encumberance=o.encumber }
 					self.max_h = math.max(self.max_h, #o:getDesc():splitLines(self.iw - 10, self.font))
 					chars[char] = #list
 					i = i + 1
@@ -152,26 +157,20 @@ function _M:generateList()
 	self.equip_list = list
 
 	-- Makes up the list
-	local list = {}
+	self.inven_list = {}
+	local list = self.inven_list
 	local chars = {}
 	local i = 0
 	for item, o in ipairs(self.actor:getInven("INVEN")) do
 		if not self.filter or self.filter(o) then
 			local char = string.char(string.byte('a') + i)
-			list[#list+1] = { name=char..") "..o:getDisplayString()..o:getName(), color=o:getDisplayColor(), object=o, inven=self.actor.INVEN_INVEN, item=item }
+			list[#list+1] = { id=#list+1, char=char, name=o:getDisplayString()..o:getName(), color=o:getDisplayColor(), object=o, inven=self.actor.INVEN_INVEN, item=item, cat=o.type.."/"..o.subtype, encumberance=o.encumber }
 			self.max_h = math.max(self.max_h, #o:getDesc():splitLines(self.iw - 10, self.font))
 			chars[char] = #list
 			i = i + 1
 		end
 	end
 	list.chars = chars
-	self.inven_list = list
-	self.changed = true
-
-	self.list = self.inven_list
-	self.sel = 1
-	self.scroll = 1
-	self.max = math.floor((self.ih - 5) / self.font_h) - self.max_h
 end
 
 function _M:on_recover_focus()
diff --git a/game/engines/default/engine/ui/Dialog.lua b/game/engines/default/engine/ui/Dialog.lua
index 5682f154f774be600912eb925aee0db20e84a560..a19b84ebcd23a48a98174825f3e5b3f77ab7e7b6 100644
--- a/game/engines/default/engine/ui/Dialog.lua
+++ b/game/engines/default/engine/ui/Dialog.lua
@@ -24,9 +24,80 @@ local Base = require "engine.ui.Base"
 --- A generic UI button
 module(..., package.seeall, class.inherit(Base))
 
+--- Requests a simple, press any key, dialog
+function _M:simplePopup(title, text, fct, no_leave)
+	local w, h = self.font:size(text)
+	local tw, th = self.font:size(title)
+	local d = new(title, math.max(w, tw) + 20, h + 75)
+	d:loadUI{{left = 3, top = 3, ui=require("engine.ui.Textzone").new{width=w+10, height=h+5, text=text}}}
+	if not no_leave then
+		d.key:addBind("EXIT", function() game:unregisterDialog(d) if fct then fct() end end)
+		local close = require("engine.ui.Button").new{text="Close", fct=function() d.key:triggerVirtual("EXIT") end}
+		d:loadUI{no_reset=true, {hcenter = -close.w / 2, bottom = 3, ui=close}}
+		d:setFocus(close)
+	end
+	game:registerDialog(d)
+	return d
+end
+
+--- Requests a simple, press any key, dialog
+function _M:simpleLongPopup(title, text, w, fct, no_leave)
+	local list = text:splitLines(w - 10, self.font)
+	local d = new(title, w + 20, #list * self.font_h + 75)
+	d:loadUI{{left = 3, top = 3, ui=require("engine.ui.Textzone").new{width=w+10, height=self.font_h * #list, text=text}}}
+	if not no_leave then
+		d.key:addBind("EXIT", function() game:unregisterDialog(d) if fct then fct() end end)
+		local close = require("engine.ui.Button").new{text="Close", fct=function() d.key:triggerVirtual("EXIT") end}
+		d:loadUI{no_reset=true, {hcenter = -close.w / 2, bottom = 3, ui=close}}
+		d:setFocus(close)
+	end
+	game:registerDialog(d)
+	return d
+end
+
+--- Requests a simple yes-no dialog
+function _M:yesnoPopup(title, text, fct, yes_text, no_text)
+	local w, h = self.font:size(text)
+	local tw, th = self.font:size(title)
+	local d = new(title, math.max(w, tw) + 35, h + 75)
+
+	d.key:addBind("EXIT", function() game:unregisterDialog(d) fct(false) end)
+	local ok = require("engine.ui.Button").new{text=yes_text or "Yes", fct=function() game:unregisterDialog(d) fct(true) end}
+	local cancel = require("engine.ui.Button").new{text=no_text or "No", fct=function() game:unregisterDialog(d) fct(false) end}
+	d:loadUI{
+		{left = 3, top = 3, ui=require("engine.ui.Textzone").new{width=w+20, height=h+5, text=text}},
+		{left = 3, bottom = 3, ui=ok},
+		{right = 3, bottom = 3, ui=cancel},
+	}
+	d:setFocus(ok)
+
+	game:registerDialog(d)
+	return d
+end
+
+--- Requests a long yes-no dialog
+function _M:yesnoLongPopup(title, text, w, fct, yes_text, no_text)
+	local list = text:splitLines(w - 10, font)
+	local d = new(title, w + 20, #list * self.font_h + 75)
+
+	d.key:addBind("EXIT", function() game:unregisterDialog(d) fct(false) end)
+	local ok = require("engine.ui.Button").new{text=yes_text or "Yes", fct=function() game:unregisterDialog(d) fct(true) end}
+	local cancel = require("engine.ui.Button").new{text=no_text or "No", fct=function() game:unregisterDialog(d) fct(false) end}
+	d:loadUI{
+		{left = 3, top = 3, ui=require("engine.ui.Textzone").new{width=w+20, height=self.font_h * #list, text=text}}}
+		{left = 3, bottom = 3, ui=ok},
+		{right = 3, bottom = 3, ui=cancel},
+	}
+	d:setFocus(ok)
+
+	game:registerDialog(d)
+	return d
+end
+
+
 function _M:init(title, w, h, x, y, alpha, font, showup)
 	self.title = assert(title, "no dialog title")
-	self.alpha = self.alpha or 200
+	self.alpha = self.alpha or 255
 	if showup ~= nil then
 		self.__showup = showup
 	else
@@ -85,7 +156,7 @@ function _M:generate()
 	s:drawColorStringBlended(self.font, self.title, (self.w - tw) / 2, 4, 255,255,255)
 	self.font:setStyle("normal")
 
-	self.mouse:registerZone(0, 0, gamew, gameh, function() self.key:triggerVirtual("EXIT") end)
+	self.mouse:registerZone(0, 0, gamew, gameh, function(button, x, y, xrel, yrel, bx, by, event) if button == "left" and event == "button" then  self.key:triggerVirtual("EXIT") end end)
 	self.mouse:registerZone(self.display_x, self.display_y, self.w, self.h, function(...) self:mouseEvent(...) end)
 	self.key.receiveKey = function(_, ...) self:keyEvent(...) end
 	self.key:addCommand("_TAB", function(...) self.key:triggerVirtual("MOVE_DOWN") end)
@@ -100,17 +171,24 @@ function _M:generate()
 end
 
 function _M:loadUI(t)
-	self.uis = {}
-	self.focus_ui = nil
-	self.focus_ui_id = 0
+	if not t.no_reset then
+		self.uis = {}
+		self.focus_ui = nil
+		self.focus_ui_id = 0
+	end
 	for i, ui in ipairs(t) do
 		self.uis[#self.uis+1] = ui
 
 		local ux, uy = self.ix, self.iy
+
 		if ui.top then uy = uy + ui.top
-		elseif ui.bottom then uy = uy + self.ih - ui.bottom - ui.ui.h end
+		elseif ui.bottom then uy = uy + self.ih - ui.bottom - ui.ui.h
+		elseif ui.vcenter then uy = uy + math.floor(self.ih / 2) + ui.vcenter end
+
 		if ui.left then ux = ux + ui.left
-		elseif ui.right then ux = ux + self.iw - ui.right - ui.ui.w end
+		elseif ui.right then ux = ux + self.iw - ui.right - ui.ui.w
+		elseif ui.hcenter then ux = ux + math.floor(self.iw / 2) + ui.hcenter end
+
 		ui.x = ux
 		ui.y = uy
 		ui.ui.mouse.delegate_offset_x = ux
@@ -118,8 +196,8 @@ function _M:loadUI(t)
 
 		if not self.focus_ui and ui.ui.can_focus then
 			self:setFocus(i)
-		else
-		ui.ui:setFocus(false)
+		elseif ui.ui.can_focus then
+			ui.ui:setFocus(false)
 		end
 	end
 end
@@ -127,6 +205,13 @@ end
 function _M:setFocus(id)
 	if self.focus_ui then self.focus_ui.ui:setFocus(false) end
 
+	if type(id) == "table" then
+		for i = 1, #self.uis do
+			if self.uis[i].ui == id then id = i break end
+		end
+		if type(id) == "table" then return end
+	end
+
 	local ui = self.uis[id]
 	self.focus_ui = ui
 	self.focus_ui_id = id
@@ -155,6 +240,9 @@ end
 
 function _M:display() end
 
+function _M:unload()
+end
+
 function _M:toScreen(x, y)
 	-- Draw with only the texture
 --[[
diff --git a/game/engines/default/engine/ui/List.lua b/game/engines/default/engine/ui/List.lua
index d6fac8287b4c5bc773007ab5a2a21ef262edf738..c7d833af4aa03a774ef3376bb970cda5f79ed168 100644
--- a/game/engines/default/engine/ui/List.lua
+++ b/game/engines/default/engine/ui/List.lua
@@ -126,7 +126,7 @@ function _M:onUse()
 	local item = self.list[self.sel]
 	if not item then return end
 	if item.fct then item:fct()
-	else self.fct(item) end
+	else self.fct(item, self.sel) end
 end
 
 function _M:display(x, y)
diff --git a/game/engines/default/engine/ui/ListColumns.lua b/game/engines/default/engine/ui/ListColumns.lua
index fd145b771b00ebaa38f90513080e0da989650de1..87708f437dc0d4b8382c2534027a64ac66dce93b 100644
--- a/game/engines/default/engine/ui/ListColumns.lua
+++ b/game/engines/default/engine/ui/ListColumns.lua
@@ -175,7 +175,7 @@ function _M:onUse()
 	local item = self.list[self.sel]
 	if not item then return end
 	if item.fct then item:fct()
-	else self.fct(item) end
+	else self.fct(item, self.sel) end
 end
 
 function _M:selectColumn(i, force)
@@ -190,10 +190,12 @@ function _M:selectColumn(i, force)
 		self.sort_reverse = not self.sort_reverse
 	end
 
-	local fct = col.sort
-	if type(fct) == "string" then fct = function(a, b) return a[col.sort] < b[col.sort] end end
-	if self.sort_reverse then local old=fct fct = function(a, b) return old(b, a) end end
-	table.sort(self.list, fct)
+	if self.sortable and not force then
+		local fct = col.sort
+		if type(fct) == "string" then fct = function(a, b) return a[col.sort] < b[col.sort] end end
+		if self.sort_reverse then local old=fct fct = function(a, b) return old(b, a) end end
+		table.sort(self.list, fct)
+	end
 end
 
 function _M:display(x, y)
diff --git a/game/engines/default/engine/utils.lua b/game/engines/default/engine/utils.lua
index 8b500256581c3cf386796484d2ad8b783374b90c..173d137543dc0e044c92abf9f9208cc52f32e23a 100644
--- a/game/engines/default/engine/utils.lua
+++ b/game/engines/default/engine/utils.lua
@@ -550,8 +550,8 @@ function util.showMainMenu(no_reboot)
 	if game and type(game) == "table" then game:joinThreads(30) end
 
 	if no_reboot then
---		local Menu = require("special.mainmenu.class.Game")
-		local Menu = require("special.mainmenu.class.TestUI")
+		local Menu = require("special.mainmenu.class.Game")
+--		local Menu = require("special.mainmenu.class.TestUI")
 		game = Menu.new()
 		game:run()
 	else
diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua
index 3180e5030e353d73d1c4ef08f673e521c749ddbd..47147a12d1adf79a85df1e37113c3cc5679c885f 100644
--- a/game/modules/tome/class/Game.lua
+++ b/game/modules/tome/class/Game.lua
@@ -55,7 +55,7 @@ local FlyingText = require "engine.FlyingText"
 local Tooltip = require "engine.Tooltip"
 local Calendar = require "engine.Calendar"
 
-local Dialog = require "engine.Dialog"
+local Dialog = require "engine.ui.Dialog"
 local MapMenu = require "mod.dialogs.MapMenu"
 
 module(..., package.seeall, class.inherit(engine.GameTurnBased, engine.interface.GameMusic, engine.interface.GameSound, engine.interface.GameTargeting))
@@ -830,9 +830,9 @@ function _M:onQuit()
 	self.player:restStop("quitting")
 
 	if not self.quit_dialog and not self.player.dead then
-		self.quit_dialog = Dialog:yesnoPopup("    Save and exit?    ", "Save and exit?", function(ok)
+		self.quit_dialog = Dialog:yesnoPopup("Save and exit?", "Save and exit?", function(ok)
 			if ok then
-				local d = engine.Dialog:simplePopup("Quitting...", "Quitting...")
+				local d = engine.Dialog:simplePopup("Quitting...", "Quitting...", nil, true)
 				d.__show_popup = false
 				core.display.forceRedraw()
 
diff --git a/game/modules/tome/class/interface/PlayerLore.lua b/game/modules/tome/class/interface/PlayerLore.lua
index da5590083622837493b62c70b2329c8c14bd13c1..ea43793388a1046ed58be291301a906021e5e9ad 100644
--- a/game/modules/tome/class/interface/PlayerLore.lua
+++ b/game/modules/tome/class/interface/PlayerLore.lua
@@ -18,7 +18,7 @@
 -- darkgod@te4.org
 
 require "engine.class"
-local Dialog = require "engine.Dialog"
+local Dialog = require "engine.ui.Dialog"
 
 module(..., package.seeall, class.make)