List Button Navigation Problem

Hello everybody :slightly_smiling_face:

Need your help again! My file manager is ready, but I would like to have a button navigation in the file list. The buttons are declared in the hardware libs and work when I press something. I can scroll the list but not the buttons in the list. As described here. https://forum.lvgl.io/t/list-manual-navigation-problems/3958/3

I then made a group for the list: The list is focused and the first button, but no navigation. I’ve tested various commands like in the code here. I would like to control the list buttons with up / down. Hope the code is enough to understand.
Screenshot with focus and without focus (adding a group does that), scrolling also works without a group. Need a tip or example… LVGL 5.3

Thank you very much!

Code to reproduce

Add a code snippet which can run in the simulator. It should contain only the relevant code that compiles without errors when separated from your main code base.

The code block(s) should be formatted like:

static lv_obj_t* list;//Dateiliste global

//From HW Libs, changed see at end of the funktion
static bool _jc_virt_mouse_read(lv_indev_data_t* data)
{
	// Poll Joy-Con.
	jc_gamepad_rpt_t* jc_pad = joycon_poll();

	if (!jc_pad)
	{
		data->state = LV_INDEV_STATE_REL;
		return false;
	}

	// Take a screenshot if Capture button is pressed.
	if (jc_pad->cap)
	{
		_save_fb_to_bmp();
		msleep(1000);
	}

	// Calibrate left stick.
	if (!jc_drv_ctx.centering_done)
	{
		if (jc_pad->conn_l
			&& jc_pad->lstick_x > 0x400 && jc_pad->lstick_y > 0x400
			&& jc_pad->lstick_x < 0xC00 && jc_pad->lstick_y < 0xC00)
		{
			jc_drv_ctx.cx_max = jc_pad->lstick_x + 0x72;
			jc_drv_ctx.cx_min = jc_pad->lstick_x - 0x72;
			jc_drv_ctx.cy_max = jc_pad->lstick_y + 0x72;
			jc_drv_ctx.cy_min = jc_pad->lstick_y - 0x72;
			jc_drv_ctx.centering_done = true;
			jc_drv_ctx.cursor_timeout = 0;
		}
		else
		{
			data->state = LV_INDEV_STATE_REL;
			return false;
		}
	}

	// Re-calibrate on disconnection.
	if (!jc_pad->conn_l)
		jc_drv_ctx.centering_done = 0;

	// Set button presses. //Buttons Joycon Funktion gedrückt
	if (jc_pad->a || jc_pad->zl || jc_pad->zr)
		data->state = LV_INDEV_STATE_PR;
	else
		data->state = LV_INDEV_STATE_REL;

	// Enable console. //Buttons Joycon Debug Konsole aktivieren
	if (jc_pad->plus || jc_pad->minus)
	{
		if (((u32)get_tmr_ms() - jc_drv_ctx.console_timeout) > 1000)
		{
			if (!console_enabled)
			{
				display_activate_console();
				console_enabled = true;
				gfx_con_getpos(&gfx_con.savedx, &gfx_con.savedy);
				gfx_con_setpos(964, 630);
				gfx_printf("Press -/+ to close");
				gfx_con_setpos(gfx_con.savedx, gfx_con.savedy);
			}
			else
			{
				display_deactivate_console();
				console_enabled = false;
			}

			jc_drv_ctx.console_timeout = get_tmr_ms();
		}

		data->state = LV_INDEV_STATE_REL;
		return false;
	}

	if (console_enabled)
	{
		gfx_con_getpos(&gfx_con.savedx, &gfx_con.savedy);
		gfx_con_setpos(32, 630);
		gfx_con.fntsz = 8;
		gfx_printf("x: %4X, y: %4X | b: %06X | bt: %d %0d | cx: %03X - %03x, cy: %03X - %03x",
			jc_pad->lstick_x, jc_pad->lstick_y, jc_pad->buttons,
			jc_pad->batt_info_l, jc_pad->batt_info_r,
			jc_drv_ctx.cx_min, jc_drv_ctx.cx_max, jc_drv_ctx.cy_min, jc_drv_ctx.cy_max);
		gfx_con_setpos(gfx_con.savedx, gfx_con.savedy);
		gfx_con.fntsz = 16;

		data->state = LV_INDEV_STATE_REL;
		return false;
	}

	// Calculate new cursor position.
	if (jc_pad->lstick_x <= jc_drv_ctx.cx_max && jc_pad->lstick_x >= jc_drv_ctx.cx_min)
		jc_drv_ctx.pos_x += 0;
	else if (jc_pad->lstick_x > jc_drv_ctx.cx_max)
		jc_drv_ctx.pos_x += ((jc_pad->lstick_x - jc_drv_ctx.cx_max) / 30);
	else
		jc_drv_ctx.pos_x -= ((jc_drv_ctx.cx_min - jc_pad->lstick_x) / 30);

	if (jc_pad->lstick_y <= jc_drv_ctx.cy_max && jc_pad->lstick_y >= jc_drv_ctx.cy_min)
		jc_drv_ctx.pos_y += 0;
	else if (jc_pad->lstick_y > jc_drv_ctx.cy_max)
		jc_drv_ctx.pos_y -= ((jc_pad->lstick_y - jc_drv_ctx.cy_max) / 30);
	else
		jc_drv_ctx.pos_y += ((jc_drv_ctx.cy_min - jc_pad->lstick_y) / 30);

	// Ensure value inside screen limits.
	if (jc_drv_ctx.pos_x < 0)
		jc_drv_ctx.pos_x = 0;
	else if (jc_drv_ctx.pos_x > 1279)
		jc_drv_ctx.pos_x = 1279;

	if (jc_drv_ctx.pos_y < 0)
		jc_drv_ctx.pos_y = 0;
	else if (jc_drv_ctx.pos_y > 719)
		jc_drv_ctx.pos_y = 719;

	// Set cursor position.
	data->point.x = jc_drv_ctx.pos_x;
	data->point.y = jc_drv_ctx.pos_y;

	// Auto hide cursor.
	if (jc_drv_ctx.pos_x != jc_drv_ctx.pos_last_x || jc_drv_ctx.pos_y != jc_drv_ctx.pos_last_y)
	{
		jc_drv_ctx.pos_last_x = jc_drv_ctx.pos_x;
		jc_drv_ctx.pos_last_y = jc_drv_ctx.pos_y;

		jc_drv_ctx.cursor_hidden = false;
		jc_drv_ctx.cursor_timeout = get_tmr_ms();
		lv_indev_set_cursor(jc_drv_ctx.indev, jc_drv_ctx.cursor);

		// Un hide cursor.
		lv_obj_set_opa_scale_enable(jc_drv_ctx.cursor, false);
	}
	else
	{
		if (!jc_drv_ctx.cursor_hidden)
		{
			if (((u32)get_tmr_ms() - jc_drv_ctx.cursor_timeout) > 3000)
			{
				// Remove cursor and hide it.
				lv_indev_set_cursor(jc_drv_ctx.indev, NULL);
				lv_obj_set_opa_scale_enable(jc_drv_ctx.cursor, true);
				lv_obj_set_opa_scale(jc_drv_ctx.cursor, LV_OPA_TRANSP);

				jc_drv_ctx.cursor_hidden = true;
			}
		}
		else
			data->state = LV_INDEV_STATE_REL; // Ensure that no clicks are allowed.
	}










	//Button Joycon Funktion schliessen geändert zu x
	if (jc_pad->x && close_btn)
	{
		lv_action_t close_btn_action = lv_btn_get_action(close_btn, LV_BTN_ACTION_CLICK);
		close_btn_action(close_btn);
		close_btn = NULL;
	}

	//Button Joycon Funktion Folder Back b
	if (jc_pad->b && btn_back)
	{
		lv_action_t back_btn_action = lv_btn_get_action(btn_back, LV_BTN_ACTION_CLICK);//reagiert extrem schnell geht manchmal mehrere Ordner zurück
		//lv_action_t back_btn_action = lv_btn_get_action(btn_back, LV_BTN_ACTION_LONG_PR_REPEAT);//alles andere verursacht error
		back_btn_action(btn_back);
		//btn_back = NULL;
	}

	//Button Joycon Funktion hier freeze wenn im Hauptmenü, mit (&& list) ok
	if (jc_pad->up && list)
	{
		lv_list_up(list);//Scrollen ok
	}

	if (jc_pad->down && list)
	{
		lv_list_down(list);//Scrollen ok

		//lv_list_focus(btn, false);//Auf erster Listeninhalt fokusieren
		//lv_list_get_next_btn(list, NULL);

		//LV_GROUP_KEY_NEXT;

		//lv_obj_t* focus = lv_list_get_next_btn(list, NULL);
		//lv_list_focus(focus, true);//Auf erster Listeninhalt fokusieren

	}

	//LV_GROUP_KEY_DOWN

	//LV_KEY_RIGHT / DOWN Select the next button

	//LV_KEY_LEFT / UP Select the previous button


	//lv_list_focus(btn, false);//Auf erster Listeninhalt fokusieren
	//lv_list_down(list);
	//lv_obj_t* focus = lv_list_get_next_btn(list, NULL);
	//lv_list_focus(focus, true);//Auf erster Listeninhalt fokusieren

	return false; // No buffering so no more data read.
}


//File und Folder List Filemanager erstellen
void create_filemenu(const char* path, lv_obj_t* parent)
{

	//You can navigate manually in the list with lv_list_up(list) and lv_list_down(list) .
	//You can focus on a button directly using lv_list_focus(btn, anim_en) .
	//The animation time of up / down / focus movements can be set via : lv_list_set_anim_time(list, anim_time).Zero animation time means not animations.
	//I added lv_list_set_btn_selected(list, btn) and lv_list_get_btn_selected(list) function.


	list = lv_list_create(win_fm, NULL);//only sample..........



	//Benötigt USE_LV_GROUP 1, Wenn aktiviert ist die Liste eingerahmt und der erste Button angewählt
	lv_group_t* listnav = lv_group_create();
	lv_group_add_obj(listnav, list);

}