瀏覽代碼

modal window

John Dodis 1 年之前
父節點
當前提交
542d20d4eb
共有 2 個文件被更改,包括 68 次插入25 次删除
  1. 20 6
      main.lua
  2. 48 19
      ui2d/ui2d.lua

+ 20 - 6
main.lua

@@ -17,6 +17,7 @@ local txt1 = "Αυτό είναι utf8 κείμενο"
 local txt2 = "Another textbox"
 local amplitude = 50
 local frequency = 0.1
+local modal_window_open = false
 
 function lovr.load()
 	UI2D.Init()
@@ -36,7 +37,7 @@ function lovr.draw( pass )
 	-- pass:plane( 100, 100, 0, 100, 100 )
 	UI2D.NewFrame( pass )
 
-	UI2D.Begin( "first", 300, 300 )
+	UI2D.Begin( "first", 100, 200 )
 	if UI2D.Button( "first button" ) then
 		print( "from 1st button" )
 	end
@@ -61,7 +62,7 @@ function lovr.draw( pass )
 	end
 	UI2D.End( pass )
 
-	UI2D.Begin( "second", 400, 200 )
+	UI2D.Begin( "second", 300, 50 )
 	UI2D.Label( "We're doing progress...", true )
 	UI2D.ProgressBar( progress.value )
 	UI2D.Separator()
@@ -78,8 +79,10 @@ function lovr.draw( pass )
 	UI2D.Button( "second button2" )
 	UI2D.End( pass )
 
-	UI2D.Begin( "third", 350, 240 )
-	UI2D.Button( "blah1" )
+	UI2D.Begin( "third", 700, 100 )
+	if UI2D.Button( "Open modal window" ) then
+		modal_window_open = true
+	end
 	UI2D.OverrideColor( "button_bg", { 0.8, 0, 0.8 } )
 	UI2D.Button( "colored button" )
 	UI2D.ResetColor( "button_bg" )
@@ -89,7 +92,7 @@ function lovr.draw( pass )
 	UI2D.End( pass )
 
 	UI2D.OverrideColor( "window_bg", { 0.1, 0.2, 0.6 } )
-	UI2D.Begin( "Colored window", 250, 250 )
+	UI2D.Begin( "Colored window", 650, 300 )
 	UI2D.Button( txt )
 	UI2D.SameLine()
 	txt1 = UI2D.TextBox( "textbox1", 11, txt1 )
@@ -105,7 +108,7 @@ function lovr.draw( pass )
 	UI2D.End( pass )
 	UI2D.ResetColor( "window_bg" )
 
-	UI2D.Begin( "TabBar window", 350, 100 )
+	UI2D.Begin( "TabBar window", 350, 350 )
 	local was_clicked, idx = UI2D.TabBar( "my tab bar", { "first", "second", "third" }, tab_bar_idx )
 	if was_clicked then
 		tab_bar_idx = idx
@@ -125,6 +128,17 @@ function lovr.draw( pass )
 	end
 	UI2D.End( pass )
 
+	-- Modal window
+	if modal_window_open then
+		UI2D.Begin( "Modal window", 300, 200, true )
+		UI2D.Label( "Close this window\nto interact with other windows" )
+		if UI2D.Button( "Close" ) then
+			modal_window_open = false
+			UI2D.EndModalWindow()
+		end
+		UI2D.End( pass )
+	end
+
 	local ui_passes = UI2D.RenderFrame( pass )
 	table.insert( ui_passes, pass )
 	return lovr.graphics.submit( ui_passes )

+ 48 - 19
ui2d/ui2d.lua

@@ -8,6 +8,7 @@ local active_window = nil
 local active_widget = nil
 local active_textbox = nil
 local dragged_window = nil
+local modal_window = nil
 local repeating_key = nil
 local text_input_character = nil
 local begin_idx = nil
@@ -236,7 +237,7 @@ local function Slider( type, name, v, v_min, v_max, width )
 	local col = colors.slider_bg
 	local result = false
 
-	if not modal_window or (modal_window and modal_window == cur_window.id) then
+	if not modal_window or (modal_window and modal_window == cur_window) then
 		if PointInRect( mouse.x, mouse.y, bbox.x + cur_window.x, bbox.y + cur_window.y, slider_w, bbox.h ) and cur_window == active_window then
 			col = colors.slider_bg_hover
 
@@ -372,10 +373,14 @@ function UI2D.InputInfo()
 			end
 		end
 
-		if win then
-			next_z = next_z + 0.01
-			win.z = next_z
-			active_window = win
+		if modal_window then
+			active_window = modal_window
+		else
+			if win then
+				next_z = next_z + 0.01
+				win.z = next_z
+				active_window = win
+			end
 		end
 	end
 
@@ -430,9 +435,14 @@ function UI2D.Begin( name, x, y, is_modal )
 			texture_h = 0,
 			pass = nil,
 			is_hovered = false,
-			is_modal = is_modal or false
+			is_modal = is_modal or false,
+			was_called_this_frame = true
 		}
 		table.insert( windows, window )
+
+		if is_modal then
+			modal_window = window
+		end
 	end
 	layout.y = (2 * margin) + font.h
 
@@ -441,6 +451,10 @@ function UI2D.Begin( name, x, y, is_modal )
 	else
 		begin_idx = idx
 	end
+
+	if idx > 0 then
+		windows[ idx ].was_called_this_frame = true
+	end
 end
 
 function UI2D.End( main_pass )
@@ -597,6 +611,10 @@ function UI2D.GetFontSize()
 	return font.size
 end
 
+function UI2D.EndModalWindow()
+	modal_window = nil
+end
+
 function UI2D.SameLine()
 	layout.same_line = true
 end
@@ -632,7 +650,7 @@ function UI2D.Button( name, width, height )
 	local result = false
 	local col = colors.button_bg
 
-	if not modal_window or (modal_window and modal_window == cur_window.id) then
+	if not modal_window or (modal_window and modal_window == cur_window) then
 		if PointInRect( mouse.x, mouse.y, bbox.x + cur_window.x, bbox.y + cur_window.y, bbox.w, bbox.h ) and cur_window == active_window then
 			col = colors.button_bg_hover
 			if mouse.state == e_mouse_state.clicked then
@@ -733,7 +751,7 @@ function UI2D.ImageButton( texture, width, height, text )
 	local result = false
 	local col = 1
 
-	if not modal_window or (modal_window and modal_window == cur_window.id) then
+	if not modal_window or (modal_window and modal_window == cur_window) then
 		if PointInRect( mouse.x, mouse.y, bbox.x + cur_window.x, bbox.y + cur_window.y, bbox.w, bbox.h ) and cur_window == active_window then
 			table.insert( windows[ begin_idx ].command_list, { type = "rect_wire", bbox = bbox, color = colors.image_button_border_highlight } )
 
@@ -790,7 +808,7 @@ function UI2D.TabBar( name, tabs, idx )
 		local tab_w = text_w + (2 * margin)
 		bbox.w = bbox.w + tab_w
 
-		if not modal_window or (modal_window and modal_window == cur_window.id) then
+		if not modal_window or (modal_window and modal_window == cur_window) then
 			if PointInRect( mouse.x, mouse.y, x_off + cur_window.x, bbox.y + cur_window.y, tab_w, bbox.h ) and cur_window == active_window then
 				col = colors.tab_bar_hover
 				if mouse.state == e_mouse_state.clicked then
@@ -866,7 +884,7 @@ function UI2D.CheckBox( text, checked )
 	local result = false
 	local col = colors.check_border
 
-	if not modal_window or (modal_window and modal_window == cur_window.id) then
+	if not modal_window or (modal_window and modal_window == cur_window) then
 		if PointInRect( mouse.x, mouse.y, bbox.x + cur_window.x, bbox.y + cur_window.y, bbox.w, bbox.h ) and cur_window == active_window then
 			col = colors.check_border_hover
 			if mouse.state == e_mouse_state.clicked then
@@ -903,7 +921,7 @@ function UI2D.RadioButton( text, checked )
 	local result = false
 	local col = colors.radio_border
 
-	if not modal_window or (modal_window and modal_window == cur_window.id) then
+	if not modal_window or (modal_window and modal_window == cur_window) then
 		if PointInRect( mouse.x, mouse.y, bbox.x + cur_window.x, bbox.y + cur_window.y, bbox.w, bbox.h ) and cur_window == active_window then
 			col = colors.radio_border_hover
 
@@ -1026,7 +1044,7 @@ function UI2D.TextBox( name, num_visible_chars, text )
 	local col1 = colors.textbox_bg
 	local col2 = colors.textbox_border
 
-	if not modal_window or (modal_window and modal_window == cur_window.id) then
+	if not modal_window or (modal_window and modal_window == cur_window) then
 		if PointInRect( mouse.x, mouse.y, text_rect.x + cur_window.x, text_rect.y + cur_window.y, text_rect.w, text_rect.h ) and cur_window == active_window then
 			col1 = colors.textbox_bg_hover
 
@@ -1111,7 +1129,7 @@ end
 -- 	local released = false
 -- 	local hovered = false
 
--- 	if not modal_window or (modal_window and modal_window == cur_window.id) then
+-- 	if not modal_window or (modal_window and modal_window == cur_window) then
 -- 		if PointInRect( mouse.x, mouse.y, bbox.x + cur_window.x, bbox.y + cur_window.y, bbox.w, bbox.h ) and cur_window == active_window then
 -- 			hovered = true
 
@@ -1138,13 +1156,23 @@ function UI2D.NewFrame( main_pass )
 end
 
 function UI2D.RenderFrame( main_pass )
-	table.sort( windows, function( a, b ) return a.z < b.z end )
+	table.sort( windows, function( a, b ) return a.z > b.z end )
 
-	for i, v in ipairs( windows ) do
-		main_pass:setColor( 1, 1, 1 )
-		main_pass:setMaterial( v.texture )
-		main_pass:plane( v.x + (v.w / 2), v.y + (v.h / 2), 0, v.w, -v.h ) --NOTE flip Y fix
-		main_pass:setMaterial()
+	local count = #windows
+	for i = count, 1, -1 do
+		local win = windows[ i ]
+
+		if win.was_called_this_frame then
+			main_pass:setColor( 1, 1, 1 )
+			if modal_window and win ~= modal_window then
+				main_pass:setColor( colors.modal_tint )
+			end
+			main_pass:setMaterial( win.texture )
+			main_pass:plane( win.x + (win.w / 2), win.y + (win.h / 2), 0, win.w, -win.h ) --NOTE flip Y fix
+			main_pass:setMaterial()
+		else
+			table.remove( windows, i )
+		end
 	end
 
 	text_input_character = nil
@@ -1153,6 +1181,7 @@ function UI2D.RenderFrame( main_pass )
 	for i, v in ipairs( windows ) do
 		v.command_list = nil
 		v.command_list = {}
+		v.was_called_this_frame = false
 		table.insert( passes, v.pass )
 	end
 	return passes