update location and setting

This commit is contained in:
Kivy Signage Player
2025-09-30 10:36:30 +03:00
parent e052f4d068
commit 88b28a5937
9 changed files with 75 additions and 107 deletions

BIN
config/resources/arrow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
config/resources/exit.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
config/resources/pause.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
config/resources/play.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -18,6 +18,7 @@ from kivy.uix.popup import Popup
from kivy.uix.textinput import TextInput
from kivy.clock import Clock
from kivy.core.window import Window
from kivy.properties import BooleanProperty
from kivy.logger import Logger
from kivy.animation import Animation
from kivy.lang import Builder
@@ -61,9 +62,20 @@ class SettingsPopup(Popup):
class SignagePlayer(Widget):
from kivy.properties import StringProperty
resources_path = StringProperty()
from kivy.properties import NumericProperty
screen_width = NumericProperty(0)
screen_height = NumericProperty(0)
def set_screen_size(self):
"""Get the current screen size and set as properties."""
self.screen_width, self.screen_height = Window.size
Logger.info(f"Screen size detected: {self.screen_width}x{self.screen_height}")
is_paused = BooleanProperty(False)
def __init__(self, **kwargs):
super(SignagePlayer, self).__init__(**kwargs)
# Initialize variables
self.playlist = []
self.current_index = 0
@@ -72,27 +84,33 @@ class SignagePlayer(Widget):
self.is_paused = False
self.config = {}
self.playlist_version = None
# Paths
self.base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
self.config_dir = os.path.join(self.base_dir, 'config')
self.media_dir = os.path.join(self.base_dir, 'media')
self.playlists_dir = os.path.join(self.base_dir, 'playlists')
self.config_file = os.path.join(self.config_dir, 'app_config.json')
self.resources_path = os.path.join(self.config_dir, 'resources')
# Create directories if they don't exist
for directory in [self.config_dir, self.media_dir, self.playlists_dir]:
os.makedirs(directory, exist_ok=True)
# Get and set screen size
self.set_screen_size()
# Bind to window size for fullscreen
Window.bind(size=self._update_size)
self._update_size(Window, Window.size)
# Initialize player
Clock.schedule_once(self.initialize_player, 0.1)
# Hide controls timer
self.controls_timer = None
# Auto-hide controls
self.schedule_hide_controls()
def _update_size(self, instance, value):
self.size = value
if hasattr(self, 'ids') and 'content_area' in self.ids:
self.ids.content_area.size = value
def initialize_player(self, dt):
"""Initialize the player - load config and start playlist checking"""
Logger.info("SignagePlayer: Initializing player...")
@@ -311,15 +329,11 @@ class SignagePlayer(Widget):
source=image_path,
allow_stretch=True,
keep_ratio=False,
size_hint=(1, 1),
pos_hint={'x': 0, 'y': 0}
size_hint=(1, 1)
)
self.ids.content_area.add_widget(self.current_widget)
# Schedule next media after duration
Clock.schedule_once(self.next_media, duration)
except Exception as e:
Logger.error(f"SignagePlayer: Error playing image {image_path}: {e}")
self.next_media()
@@ -436,17 +450,13 @@ class SignagePlayer(Widget):
class SignagePlayerApp(App):
def build(self):
# Get screen resolution info
# Force fullscreen and borderless
Window.fullscreen = True
Window.borderless = True
Logger.info(f"SignagePlayerApp: Screen size: {Window.size}")
Logger.info(f"SignagePlayerApp: Available screen size: {Window.system_size if hasattr(Window, 'system_size') else 'N/A'}")
# Set window to fullscreen and borderless
Window.fullscreen = 'auto'
Window.borderless = True
# Hide cursor after 3 seconds of inactivity
Clock.schedule_once(self.hide_cursor, 3)
return SignagePlayer()
def hide_cursor(self, dt):

View File

@@ -1,6 +1,7 @@
#:kivy 2.1.0
<SignagePlayer>:
<SignagePlayer@FloatLayout>:
size: root.screen_width, root.screen_height
canvas.before:
Color:
rgba: 0, 0, 0, 1
@@ -8,18 +9,19 @@
size: self.size
pos: self.pos
# Main content area - FULLSCREEN WIDGET
Widget:
# Main content area for images/videos
FloatLayout:
id: content_area
size_hint: 1, 1
size: root.screen_width, root.screen_height
size_hint: None, None
pos_hint: {'x': 0, 'y': 0}
# Status label overlay (shown when no content or errors)
# Status label overlay (centered)
Label:
id: status_label
text: 'Loading...'
size_hint: None, None
size: dp(400), dp(60)
size_hint: 0.5, 0.5
size: dp(600), dp(120)
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
color: 1, 1, 1, 1
font_size: sp(18)
@@ -34,109 +36,65 @@
pos: self.pos
radius: [dp(15)]
# Control panel overlay (always on top)
# Control panel overlay (bottom center, 5 columns, 1 row)
BoxLayout:
id: controls_layout
orientation: 'horizontal'
size_hint: None, None
size: dp(450), dp(60)
pos_hint: {'right': 0.98, 'top': 0.98}
opacity: 0
spacing: dp(5)
size: dp(340), dp(70)
pos_hint: {'center_x': 0.5, 'y': 0.02}
opacity: 1
spacing: dp(10)
padding: dp(10)
canvas.before:
Color:
rgba: 0.1, 0.1, 0.1, 0.9
rgba: 0.1, 0.1, 0.1, 0.9 # 90% transparent
RoundedRectangle:
size: self.size
pos: self.pos
radius: [dp(15)]
# Control buttons
radius: [dp(20)]
Button:
id: prev_btn
text: '⏮'
id: backward_btn
size_hint: None, None
size: dp(60), dp(50)
font_size: sp(18)
background_color: 0.2, 0.2, 0.2, 0.9
color: 1, 1, 1, 1
size: dp(60), dp(60)
background_normal: root.resources_path + '/backward.png'
background_down: root.resources_path + '/backward.png'
background_color: 1, 1, 1, 0
on_press: root.previous_media()
canvas.before:
Color:
rgba: self.background_color
RoundedRectangle:
size: self.size
pos: self.pos
radius: [dp(8)]
Button:
id: play_pause_btn
text: '⏸'
size_hint: None, None
size: dp(60), dp(50)
font_size: sp(18)
background_color: 0.2, 0.6, 0.2, 0.9
color: 1, 1, 1, 1
size: dp(60), dp(60)
background_normal: root.resources_path + '/play.png'
background_down: root.resources_path + '/pause.png'
background_color: 1, 1, 1, 0
on_press: root.toggle_pause()
canvas.before:
Color:
rgba: self.background_color
RoundedRectangle:
size: self.size
pos: self.pos
radius: [dp(8)]
Button:
id: next_btn
text: '⏭'
size_hint: None, None
size: dp(60), dp(50)
font_size: sp(18)
background_color: 0.2, 0.2, 0.2, 0.9
color: 1, 1, 1, 1
on_press: root.next_media()
canvas.before:
Color:
rgba: self.background_color
RoundedRectangle:
size: self.size
pos: self.pos
radius: [dp(8)]
Button:
id: settings_btn
text: '⚙'
size_hint: None, None
size: dp(60), dp(50)
font_size: sp(18)
background_color: 0.4, 0.4, 0.2, 0.9
color: 1, 1, 1, 1
size: dp(60), dp(60)
background_normal: root.resources_path + '/settings.png'
background_down: root.resources_path + '/settings.png'
background_color: 1, 1, 1, 0
on_press: root.show_settings()
canvas.before:
Color:
rgba: self.background_color
RoundedRectangle:
size: self.size
pos: self.pos
radius: [dp(8)]
Button:
id: exit_btn
text: '⏻'
size_hint: None, None
size: dp(60), dp(50)
font_size: sp(18)
background_color: 0.6, 0.2, 0.2, 0.9
color: 1, 1, 1, 1
on_press: root.exit_app()
canvas.before:
Color:
rgba: self.background_color
RoundedRectangle:
size: self.size
pos: self.pos
radius: [dp(8)]
size: dp(60), dp(60)
background_normal: root.resources_path + '/exit.png'
background_down: root.resources_path + '/exit.png'
background_color: 1, 1, 1, 0
on_press: app.stop()
Button:
id: forward_btn
size_hint: None, None
size: dp(60), dp(60)
background_normal: root.resources_path + '/forward.png'
background_down: root.resources_path + '/forward.png'
background_color: 1, 1, 1, 0
on_press: root.next_media()
# Settings popup content