Ver código fonte

color stuff/TabBar fix/textbox fixes

John Dodis 1 ano atrás
pai
commit
c9c674e792
3 arquivos alterados com 189 adições e 52 exclusões
  1. 1 0
      conf.lua
  2. 26 14
      main.lua
  3. 162 38
      ui2d/ui2d.lua

+ 1 - 0
conf.lua

@@ -2,6 +2,7 @@ function lovr.conf( t )
 	t.headset = false
 	t.headset = false
 	-- t.headset.drivers = {'desktop'}
 	-- t.headset.drivers = {'desktop'}
 	-- t.graphics.debug = true
 	-- t.graphics.debug = true
+	t.window.resizable = true
 	t.window.width = 1200
 	t.window.width = 1200
 	t.window.height = 600
 	t.window.height = 600
 end
 end

+ 26 - 14
main.lua

@@ -12,31 +12,32 @@ local tab_bar_idx = 1
 local check1 = true
 local check1 = true
 local check2 = false
 local check2 = false
 local rb_idx = 1
 local rb_idx = 1
+local progress = { value = 0, adder = 0 }
 local txt1 = "Αυτό είναι utf8 κείμενο"
 local txt1 = "Αυτό είναι utf8 κείμενο"
--- local txt1 = "here we are now hello"
 
 
 function lovr.load()
 function lovr.load()
-	UI2D.Init( 16 )
+	UI2D.Init( 14 )
 end
 end
 
 
 function lovr.update( dt )
 function lovr.update( dt )
 	UI2D.InputInfo()
 	UI2D.InputInfo()
-end
 
 
-function lovr.keypressed( key, scancode, repeating )
-	-- txt = txt .. "0"
-	-- UI2D.SetWindowPosition( "third##blah", 100, 150 )
+	progress.adder = progress.adder + (10 * dt)
+	if progress.adder > 100 then progress.adder = 0 end
+	progress.value = math.floor( progress.adder )
 end
 end
 
 
 function lovr.draw( pass )
 function lovr.draw( pass )
 	pass:setProjection( 1, mat4():orthographic( pass:getDimensions() ) )
 	pass:setProjection( 1, mat4():orthographic( pass:getDimensions() ) )
+	pass:setColor( 1, 0, 0 )
+	pass:plane( 100, 100, 0, 100, 100 )
 	UI2D.NewFrame( pass )
 	UI2D.NewFrame( pass )
 
 
 	UI2D.Begin( "first", 300, 300 )
 	UI2D.Begin( "first", 300, 300 )
 	if UI2D.Button( "first button" ) then
 	if UI2D.Button( "first button" ) then
 		print( "from 1st button" )
 		print( "from 1st button" )
 	end
 	end
-	if UI2D.ImageButton( icon, 40, 40 ) then
+	if UI2D.ImageButton( icon, 32, 32, "img button" ) then
 		print( "img" )
 		print( "img" )
 	end
 	end
 	if UI2D.RadioButton( "Radio1", rb_idx == 1 ) then
 	if UI2D.RadioButton( "Radio1", rb_idx == 1 ) then
@@ -48,11 +49,18 @@ function lovr.draw( pass )
 	if UI2D.RadioButton( "Radio3", rb_idx == 3 ) then
 	if UI2D.RadioButton( "Radio3", rb_idx == 3 ) then
 		rb_idx = 3
 		rb_idx = 3
 	end
 	end
-	UI2D.Button( "second button" )
+	if UI2D.Button( "Change theme" ) then
+		if UI2D.GetColorTheme() == "light" then
+			UI2D.SetColorTheme( "dark" )
+		else
+			UI2D.SetColorTheme( "light" )
+		end
+	end
 	UI2D.End( pass )
 	UI2D.End( pass )
 
 
 	UI2D.Begin( "second", 400, 200 )
 	UI2D.Begin( "second", 400, 200 )
-	UI2D.ProgressBar( 20 )
+	UI2D.Label( "We're doing progress...", true )
+	UI2D.ProgressBar( progress.value )
 	UI2D.Separator()
 	UI2D.Separator()
 	UI2D.Button( "first button2" )
 	UI2D.Button( "first button2" )
 	UI2D.Button( "first button2" )
 	UI2D.Button( "first button2" )
@@ -65,12 +73,16 @@ function lovr.draw( pass )
 
 
 	UI2D.Begin( "third", 350, 240 )
 	UI2D.Begin( "third", 350, 240 )
 	UI2D.Button( "blah1" )
 	UI2D.Button( "blah1" )
-	UI2D.Button( "blah2" )
+	UI2D.OverrideColor( "button_bg", { 0.8, 0, 0.8 } )
+	UI2D.Button( "colored button" )
+	UI2D.ResetColor( "button_bg" )
+	UI2D.Button( "blah3" )
 	UI2D.SameLine()
 	UI2D.SameLine()
 	released, sl2 = UI2D.SliderInt( "hello", sl2, 0, 100 )
 	released, sl2 = UI2D.SliderInt( "hello", sl2, 0, 100 )
 	UI2D.End( pass )
 	UI2D.End( pass )
 
 
-	UI2D.Begin( "fourth", 250, 250 )
+	UI2D.OverrideColor( "window_bg", { 0.1, 0.2, 0.6 } )
+	UI2D.Begin( "Colored window", 250, 250 )
 	UI2D.Button( txt )
 	UI2D.Button( txt )
 	UI2D.SameLine()
 	UI2D.SameLine()
 	txt1 = UI2D.TextBox( "textbox1", 11, txt1 )
 	txt1 = UI2D.TextBox( "textbox1", 11, txt1 )
@@ -82,6 +94,7 @@ function lovr.draw( pass )
 	end
 	end
 	released, sl3 = UI2D.SliderFloat( "hello", sl3, 0, 100, 300 )
 	released, sl3 = UI2D.SliderFloat( "hello", sl3, 0, 100, 300 )
 	UI2D.End( pass )
 	UI2D.End( pass )
+	UI2D.ResetColor( "window_bg" )
 
 
 	UI2D.Begin( "TabBar window", 350, 100 )
 	UI2D.Begin( "TabBar window", 350, 100 )
 	local was_clicked, idx = UI2D.TabBar( "my tab bar", { "first", "second", "third" }, tab_bar_idx )
 	local was_clicked, idx = UI2D.TabBar( "my tab bar", { "first", "second", "third" }, tab_bar_idx )
@@ -105,9 +118,8 @@ function lovr.draw( pass )
 
 
 	local ui_passes = UI2D.RenderFrame( pass )
 	local ui_passes = UI2D.RenderFrame( pass )
 
 
-	pass:setColor( 1, 0, 0 )
-	pass:plane( 100, 100, 0, 100, 100 )
+	-- pass:setColor( 1, 0, 0 )
+	-- pass:plane( 100, 100, 0, 100, 100 )
 	table.insert( ui_passes, pass )
 	table.insert( ui_passes, pass )
-	-- print( #ui_passes )
 	return lovr.graphics.submit( ui_passes )
 	return lovr.graphics.submit( ui_passes )
 end
 end

+ 162 - 38
ui2d/ui2d.lua

@@ -8,11 +8,14 @@ local active_window = nil
 local active_widget = nil
 local active_widget = nil
 local active_textbox = nil
 local active_textbox = nil
 local dragged_window = nil
 local dragged_window = nil
+local repeating_key = nil
+local text_input_character = nil
 local begin_idx = nil
 local begin_idx = nil
 local margin = 8
 local margin = 8
 local separator_thickness = 2
 local separator_thickness = 2
 local windows = {}
 local windows = {}
 local color_themes = {}
 local color_themes = {}
+local overriden_colors = {}
 local font = { handle = nil, w = nil, h = nil }
 local font = { handle = nil, w = nil, h = nil }
 local dragged_window_offset = { x = 0, y = 0 }
 local dragged_window_offset = { x = 0, y = 0 }
 local mouse = { x = 0, y = 0, state = e_mouse_state.idle, prev_frame = 0, this_frame = 0 }
 local mouse = { x = 0, y = 0, state = e_mouse_state.idle, prev_frame = 0, this_frame = 0 }
@@ -272,7 +275,24 @@ function utf8.sub( s, i, j )
 end
 end
 
 
 function lovr.textinput( text, code )
 function lovr.textinput( text, code )
-	--
+	text_input_character = text
+	-- print( "here")
+end
+
+function lovr.keypressed( key, scancode, repeating )
+	if repeating then
+		if key == "right" then
+			repeating_key = "right"
+		elseif key == "left" then
+			repeating_key = "left"
+		elseif key == "backspace" then
+			repeating_key = "backspace"
+		end
+	end
+end
+
+function lovr.keyreleased( key, scancode )
+	repeating_key = nil
 end
 end
 
 
 ---------------------------------------------------------------
 ---------------------------------------------------------------
@@ -281,6 +301,7 @@ function UI2D.Init( size )
 	font.handle:setPixelDensity( 1.0 )
 	font.handle:setPixelDensity( 1.0 )
 	font.h = font.handle:getHeight()
 	font.h = font.handle:getHeight()
 	font.w = font.handle:getWidth( "W" )
 	font.w = font.handle:getWidth( "W" )
+	lovr.system.setKeyRepeat( true )
 end
 end
 
 
 function UI2D.InputInfo()
 function UI2D.InputInfo()
@@ -351,14 +372,6 @@ function UI2D.InputInfo()
 	if mouse.state == e_mouse_state.released then
 	if mouse.state == e_mouse_state.released then
 		dragged_window = nil
 		dragged_window = nil
 	end
 	end
-
-	-- Unfocus textbox
-	if mouse.state == e_mouse_state.clicked then
-		if not active_textbox then
-			active_widget = nil
-			active_textbox = nil
-		end
-	end
 end
 end
 
 
 function UI2D.Begin( name, x, y, is_modal )
 function UI2D.Begin( name, x, y, is_modal )
@@ -500,6 +513,43 @@ function UI2D.SetWindowPosition( id, x, y )
 	return false
 	return false
 end
 end
 
 
+function UI2D.SetColorTheme( theme, copy_from )
+	if type( theme ) == "string" then
+		colors = color_themes[ theme ]
+	elseif type( theme ) == "table" then
+		copy_from = copy_from or "dark"
+		for i, v in pairs( color_themes[ copy_from ] ) do
+			if theme[ i ] == nil then
+				theme[ i ] = v
+			end
+		end
+		colors = theme
+	end
+end
+
+function UI2D.GetColorTheme()
+	for i, v in pairs( color_themes ) do
+		if v == colors then
+			return i
+		end
+	end
+end
+
+function UI2D.OverrideColor( col_name, color )
+	if not overriden_colors[ col_name ] then
+		local old_color = colors[ col_name ]
+		overriden_colors[ col_name ] = old_color
+		colors[ col_name ] = color
+	end
+end
+
+function UI2D.ResetColor( col_name )
+	if overriden_colors[ col_name ] then
+		colors[ col_name ] = overriden_colors[ col_name ]
+		overriden_colors[ col_name ] = nil
+	end
+end
+
 function UI2D.SameLine()
 function UI2D.SameLine()
 	layout.same_line = true
 	layout.same_line = true
 end
 end
@@ -711,8 +761,15 @@ function UI2D.TabBar( name, tabs, idx )
 		table.insert( windows[ begin_idx ].command_list, { type = "text", text = v, bbox = tab_rect, color = colors.text } )
 		table.insert( windows[ begin_idx ].command_list, { type = "text", text = v, bbox = tab_rect, color = colors.text } )
 
 
 		if idx == i then
 		if idx == i then
+			-- table.insert( windows[ begin_idx ].command_list,
+			-- 	{ type = "rect_fill", bbox = { x = tab_rect.x + 2, y = tab_rect.y + tab_rect.h - 6, w = tab_rect.w - 4, h = 5 }, color = colors.tab_bar_highlight } )
+			local highlight_thickness = math.floor( font.h / 4 )
 			table.insert( windows[ begin_idx ].command_list,
 			table.insert( windows[ begin_idx ].command_list,
-				{ type = "rect_fill", bbox = { x = tab_rect.x + 2, y = tab_rect.y + tab_rect.h - 6, w = tab_rect.w - 4, h = 5 }, color = colors.tab_bar_highlight } )
+				{
+					type = "rect_fill",
+					bbox = { x = tab_rect.x + 2, y = tab_rect.y + tab_rect.h - (highlight_thickness), w = tab_rect.w - 4, h = highlight_thickness },
+					color = colors.tab_bar_highlight
+				} )
 		end
 		end
 		x_off = x_off + tab_w
 		x_off = x_off + tab_w
 	end
 	end
@@ -834,42 +891,56 @@ function UI2D.TextBox( name, num_visible_chars, text )
 
 
 	UpdateLayout( bbox )
 	UpdateLayout( bbox )
 
 
-	local col1 = colors.textbox_bg
-	local col2 = colors.textbox_border
-
-	local text_rect = { x = bbox.x, y = bbox.y, w = (2 * margin) + (num_visible_chars * font.w), h = bbox.h }
-	if not modal_window or (modal_window and modal_window == cur_window.id) 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
-
-			if mouse.state == e_mouse_state.clicked then
-				local pos = math.floor( (mouse.x - cur_window.x - text_rect.x) / font.w )
-
-				if active_widget ~= cur_window.id .. name then
-					active_textbox = { caret = pos }
-					active_textbox.scroll = 0
-					active_widget = cur_window.id .. name
-				else
-					active_textbox.caret = pos
-				end
-			end
-		end
-	end
-
 	local scroll = 0
 	local scroll = 0
 	if active_textbox then
 	if active_textbox then
 		scroll = active_textbox.scroll
 		scroll = active_textbox.scroll
 	end
 	end
 
 
-	local visible_text = utf8.sub( text, scroll + 1, scroll + num_visible_chars )
+	local text_rect = { x = bbox.x, y = bbox.y, w = (2 * margin) + (num_visible_chars * font.w), h = bbox.h }
+	local visible_text = nil
+	if utf8.len( text ) > num_visible_chars then
+		visible_text = utf8.sub( text, scroll + 1, scroll + num_visible_chars )
+	else
+		visible_text = text
+	end
 	local label_rect = { x = text_rect.x + text_rect.w + margin, y = bbox.y, w = label_w, h = bbox.h }
 	local label_rect = { x = text_rect.x + text_rect.w + margin, y = bbox.y, w = label_w, h = bbox.h }
 	local char_rect = { x = text_rect.x + margin, y = text_rect.y, w = (utf8.len( visible_text ) * font.w), h = text_rect.h }
 	local char_rect = { x = text_rect.x + margin, y = text_rect.y, w = (utf8.len( visible_text ) * font.w), h = text_rect.h }
 
 
-
 	-- Caret
 	-- Caret
 	local caret_rect = nil
 	local caret_rect = nil
 	if active_widget == cur_window.id .. name then
 	if active_widget == cur_window.id .. name then
-		if lovr.system.wasKeyPressed( "left" ) then
+		if text_input_character then
+			local p = active_textbox.caret + active_textbox.scroll
+			local part1 = utf8.sub( text, 1, p )
+			local part2 = utf8.sub( text, p + 1, utf8.len( text ) )
+			text = part1 .. text_input_character .. part2
+			active_textbox.caret = active_textbox.caret + 1
+			if active_textbox.caret > num_visible_chars then
+				active_textbox.scroll = active_textbox.scroll + 1
+			end
+		end
+
+		if lovr.system.wasKeyPressed( "backspace" ) or repeating_key == "backspace" then
+			if active_textbox.caret > 0 then
+				local p = active_textbox.caret + active_textbox.scroll
+				local part1 = utf8.sub( text, 1, p - 1 )
+				local part2 = utf8.sub( text, p + 1, utf8.len( text ) )
+				text = part1 .. part2
+
+				local max_scroll = utf8.len( text ) - num_visible_chars
+				if active_textbox.scroll < max_scroll or utf8.len( text ) <= num_visible_chars then
+					active_textbox.caret = active_textbox.caret - 1
+				end
+				-- if active_textbox.scroll <= 0 then
+				-- 	active_textbox.caret = active_textbox.caret - 1
+				-- end
+				-- if active_textbox.scroll > max_scroll then
+				-- 	active_textbox.scroll = active_textbox.scroll - 1
+				-- end
+			end
+		end
+
+		if lovr.system.wasKeyPressed( "left" ) or repeating_key == "left" then
 			if active_textbox.caret == 0 then
 			if active_textbox.caret == 0 then
 				if active_textbox.scroll > 0 then
 				if active_textbox.scroll > 0 then
 					active_textbox.scroll = active_textbox.scroll - 1
 					active_textbox.scroll = active_textbox.scroll - 1
@@ -878,19 +949,68 @@ function UI2D.TextBox( name, num_visible_chars, text )
 			active_textbox.caret = active_textbox.caret - 1
 			active_textbox.caret = active_textbox.caret - 1
 		end
 		end
 
 
-		if lovr.system.wasKeyPressed( "right" ) then
+		if lovr.system.wasKeyPressed( "right" ) or repeating_key == "right" then
 			local full_length = utf8.len( text )
 			local full_length = utf8.len( text )
 			local visible_length = utf8.len( visible_text )
 			local visible_length = utf8.len( visible_text )
 			if active_textbox.caret == num_visible_chars and full_length > num_visible_chars and active_textbox.scroll < (full_length - visible_length) then
 			if active_textbox.caret == num_visible_chars and full_length > num_visible_chars and active_textbox.scroll < (full_length - visible_length) then
 				active_textbox.scroll = active_textbox.scroll + 1
 				active_textbox.scroll = active_textbox.scroll + 1
 			end
 			end
-			active_textbox.caret = active_textbox.caret + 1
+			if active_textbox.caret < full_length then
+				active_textbox.caret = active_textbox.caret + 1
+			end
 		end
 		end
 
 
-		active_textbox.caret = Clamp( active_textbox.caret, 0, utf8.len( visible_text ) )
+
+
+		active_textbox.scroll = Clamp( active_textbox.scroll, 0, utf8.len( text ) - num_visible_chars )
+		scroll = active_textbox.scroll
+
+		active_textbox.caret = Clamp( active_textbox.caret, 0, num_visible_chars )
+
 		caret_rect = { x = char_rect.x + (active_textbox.caret * font.w), y = char_rect.y + margin, w = 2, h = font.h }
 		caret_rect = { x = char_rect.x + (active_textbox.caret * font.w), y = char_rect.y + margin, w = 2, h = font.h }
 	end
 	end
 
 
+	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 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
+
+			if mouse.state == e_mouse_state.clicked then
+				local pos = math.floor( (mouse.x - cur_window.x - text_rect.x) / font.w )
+				if pos > utf8.len( text ) then
+					pos = utf8.len( text )
+				end
+
+				if active_widget ~= cur_window.id .. name then
+					active_textbox = { id = cur_window.id .. name, caret = pos }
+					active_textbox.scroll = 0
+					active_widget = cur_window.id .. name
+				else
+					active_textbox.caret = pos
+				end
+			end
+		else
+			if mouse.state == e_mouse_state.clicked then
+				if active_widget == cur_window.id .. name then -- Deactivate self
+					active_textbox = nil
+					active_widget = nil
+					return text
+				end
+			end
+		end
+
+		if active_widget == cur_window.id .. name then
+			if lovr.system.wasKeyPressed( "tab" ) or lovr.system.wasKeyPressed( "return" ) then -- Deactivate self
+				active_textbox = nil
+				active_widget = nil
+				return text
+			end
+		end
+	end
+
+
 	table.insert( windows[ begin_idx ].command_list, { type = "rect_fill", bbox = text_rect, color = col1 } )
 	table.insert( windows[ begin_idx ].command_list, { type = "rect_fill", bbox = text_rect, color = col1 } )
 	table.insert( windows[ begin_idx ].command_list, { type = "rect_wire", bbox = text_rect, color = col2 } )
 	table.insert( windows[ begin_idx ].command_list, { type = "rect_wire", bbox = text_rect, color = col2 } )
 	table.insert( windows[ begin_idx ].command_list, { type = "text", text = visible_text, bbox = char_rect, color = colors.text } )
 	table.insert( windows[ begin_idx ].command_list, { type = "text", text = visible_text, bbox = char_rect, color = colors.text } )
@@ -903,11 +1023,15 @@ function UI2D.TextBox( name, num_visible_chars, text )
 	return text
 	return text
 end
 end
 
 
+function UI2D.ListBox( name )
+end
+
 function UI2D.NewFrame( main_pass )
 function UI2D.NewFrame( main_pass )
 	font.handle:setPixelDensity( 1.0 )
 	font.handle:setPixelDensity( 1.0 )
 end
 end
 
 
 function UI2D.RenderFrame( main_pass )
 function UI2D.RenderFrame( main_pass )
+	text_input_character = nil
 	local passes = {}
 	local passes = {}
 
 
 	for i, v in ipairs( windows ) do
 	for i, v in ipairs( windows ) do