Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from kivy.config import Config
- Config.set('graphics', 'width', '360')
- Config.set('graphics', 'height', '640')
- Config.set('graphics', 'resizable', '0')
- from kivy.app import App
- from kivy.lang import Builder
- from kivy.animation import Animation
- from kivy.core.window import Window
- from kivy.metrics import dp
- from kivy.uix.boxlayout import BoxLayout
- from kivy.uix.button import Button
- from kivy.uix.widget import Widget
- from kivy.uix.behaviors import ButtonBehavior
- from kivy.uix.label import Label
- from kivy.uix.modalview import ModalView
- from kivy.properties import StringProperty
- from kivy.utils import platform
- Builder.load_string('''
- <ClickableOverlay>:
- canvas:
- Color:
- rgba: 0, 0, 0, 0
- Rectangle:
- pos: self.pos
- size: self.size
- <ContentItem>:
- orientation: 'horizontal'
- size_hint_y: None
- height: dp(50)
- spacing: dp(5)
- padding: dp(5)
- canvas.before:
- Color:
- rgba: 0.4, 0.4, 0.6, 1
- Rectangle:
- pos: self.pos
- size: self.size
- Label:
- id: title_label
- text: root.item_title
- size_hint_x: 0.8
- halign: 'left'
- valign: 'middle'
- text_size: self.width, None
- color: 1, 1, 1, 1
- font_size: dp(16)
- bold: True
- Button:
- id: info_button
- text: 'i'
- size_hint_x: 0.2
- size_hint_y: 1
- background_normal: ''
- background_color: 0.8, 0.8, 0.2, 1
- font_size: dp(14)
- bold: True
- on_press: root.show_info()
- <InfoDialog>:
- size_hint: (0.8, 0.5)
- auto_dismiss: True
- BoxLayout:
- orientation: 'vertical'
- padding: dp(20)
- spacing: dp(10)
- canvas.before:
- Color:
- rgba: 0.3, 0.3, 0.5, 1
- Rectangle:
- pos: self.pos
- size: self.size
- Label:
- text: root.title
- font_size: dp(20)
- bold: True
- color: 1, 1, 1, 1
- size_hint_y: 0.3
- Label:
- text: root.description
- font_size: dp(16)
- color: 1, 1, 1, 1
- text_size: self.width, None
- valign: 'top'
- halign: 'left'
- size_hint_y: 0.7
- Button:
- text: 'Close'
- size_hint_y: 0.2
- background_normal: ''
- background_color: 0.8, 0.3, 0.3, 1
- on_press: root.dismiss()
- <SearchApplicationUI>:
- orientation: 'vertical'
- spacing: dp(5)
- # Results notification panel
- BoxLayout:
- id: notification_panel
- size_hint_y: None
- height: 0
- opacity: 0
- canvas.before:
- Color:
- rgba: 0.2, 0.8, 0.4, 0.9
- Rectangle:
- pos: self.pos
- size: self.size
- Label:
- id: notification_label
- text: ''
- color: 1, 1, 1, 1
- font_size: dp(18)
- bold: True
- halign: 'center'
- padding: [dp(10), dp(5)]
- # Main content area with scrollable items
- ScrollView:
- id: content_scroll
- size_hint_y: 1
- do_scroll_y: True
- BoxLayout:
- id: items_container
- orientation: 'vertical'
- size_hint_y: None
- height: self.minimum_height
- spacing: dp(5)
- padding: [dp(10), dp(0)]
- # Search panel (fixed at the bottom)
- BoxLayout:
- id: search_controls
- size_hint_y: None
- height: dp(60)
- padding: dp(10)
- spacing: dp(5)
- TextInput:
- id: search_field
- hint_text: 'Enter search query...'
- multiline: False
- size_hint_x: 0.8
- padding: [dp(10), (self.height - self.line_height)/2]
- font_size: dp(16)
- on_focus: root.on_search_focus_changed(*args)
- on_text_validate: root.perform_search()
- Button:
- id: action_btn
- text: 'Add'
- size_hint_x: 0.2
- font_size: dp(13)
- bold: True
- background_normal: ''
- background_color: (0.4, 0.6, 0.4, 1)
- on_press: root.toggle_notification_panel()
- # Invisible overlay for keyboard dismissal
- ClickableOverlay:
- id: keyboard_dismiss_area
- size_hint_y: None
- height: 0
- on_press: root.hide_virtual_keyboard()
- ''')
- class ClickableOverlay(ButtonBehavior, Widget):
- """Transparent overlay for handling keyboard dismissal clicks"""
- pass
- class InfoDialog(ModalView):
- """Custom dialog for displaying item information"""
- title = StringProperty('')
- description = StringProperty('')
- class ContentItem(ButtonBehavior, BoxLayout):
- """Interactive content item with title and information button"""
- item_title = StringProperty('')
- item_description = StringProperty('')
- def __init__(self, item_title="", item_description="", **kwargs):
- super().__init__(**kwargs)
- self.item_title = item_title
- self.item_description = item_description
- def on_press(self):
- app = App.get_running_app()
- app.root.ids.notification_label.text = f"Selected: {self.item_title}"
- if app.root.ids.notification_panel.height == 0:
- app.root.show_notification_panel()
- def show_info(self):
- """Display information dialog for this item"""
- dialog = InfoDialog(title=self.item_title,
- description=self.item_description)
- dialog.open()
- class SearchApplicationUI(BoxLayout):
- """Main application interface with search functionality"""
- def __init__(self, **kwargs):
- super().__init__(**kwargs)
- Window.clearcolor = (0.4, 0.4, 0.4, 1)
- Window.bind(on_keyboard=self.on_keyboard)
- Window.bind(on_keyboard=self.handle_keyboard_event)
- Window.bind(on_resize=self.update_keyboard_height)
- self.initialize_content()
- def update_keyboard_height(self, window, width, height):
- """Автоматически определяем высоту клавиатуры по изменению размера окна"""
- if platform == 'android':
- # На Android Window.softinput_mode обычно изменяет размер окна
- new_height = Window.height
- if new_height < height: # Если высота уменьшилась - значит появилась клавиатура
- self.keyboard_height = height - new_height
- def handle_keyboard_event(self, window, key, *args):
- """Handle hardware back button press"""
- if key == 27: # ESC key
- if self.ids.search_field.focus:
- self.hide_virtual_keyboard()
- return True
- return False
- def initialize_content(self):
- """Populate the content area with sample items"""
- for i in range(1, 21):
- item = ContentItem(
- item_title=f'Item {i}',
- item_description=f'Detailed description for item {i}. '
- f'This contains all relevant information about the item.'
- )
- self.ids.items_container.add_widget(item)
- def on_search_focus_changed(self, instance, has_focus):
- """Handle search field focus changes"""
- self.ids.keyboard_dismiss_area.height = self.keyboard_height if has_focus else 0
- def hide_virtual_keyboard(self):
- """Dismiss the virtual keyboard"""
- self.ids.search_field.focus = False
- def toggle_notification_panel(self):
- """Toggle the notification panel visibility"""
- if self.ids.notification_panel.height == 0:
- query = self.ids.search_field.text.strip()
- if query:
- self.ids.notification_label.text = f"Added: {query}"
- self.show_notification_panel()
- else:
- self.hide_notification_panel()
- def show_notification_panel(self):
- """Animate notification panel appearance"""
- Animation(height=dp(50), opacity=1, duration=0.3).start(self.ids.notification_panel)
- self.ids.action_btn.text = "Remove"
- self.ids.action_btn.background_color = (0.8, 0.3, 0.3, 1)
- def hide_notification_panel(self):
- """Animate notification panel disappearance"""
- Animation(height=0, opacity=0, duration=0.3).start(self.ids.notification_panel)
- self.ids.action_btn.text = "Add"
- self.ids.action_btn.background_color = (0.4, 0.6, 0.4, 1)
- def perform_search(self):
- """Execute search operation"""
- query = self.ids.search_field.text.strip()
- if query:
- self.ids.notification_label.text = f"Found: {query}"
- if self.ids.notification_panel.height == 0:
- self.show_notification_panel()
- class SearchApplication(App):
- """Main application class"""
- def build(self):
- return SearchApplicationUI()
- if __name__ == '__main__':
- SearchApplication().run()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement