261 lines
9.6 KiB
Python
261 lines
9.6 KiB
Python
from kivy.app import App
|
||
from kivy.uix.button import Button
|
||
from kivy.uix.label import Label
|
||
from kivy.uix.boxlayout import BoxLayout
|
||
from kivy.uix.scrollview import ScrollView
|
||
from kivy.core.window import Window
|
||
from kivy.clock import Clock
|
||
from kivy.metrics import dp
|
||
from kivy.properties import StringProperty, ListProperty, BooleanProperty
|
||
from kivy.animation import Animation
|
||
from kivy.uix.behaviors import ButtonBehavior
|
||
from export_opened_to_raster import export_opened_to_raster
|
||
from save_to_iges import save_opened_to_iges
|
||
from get_all_sheets import get_all_sheets
|
||
from project_support import project_support
|
||
from get_opened_files import get_opened_files
|
||
|
||
|
||
class HoverBehavior(ButtonBehavior):
|
||
"""Поведение для обработки наведения курсора"""
|
||
hovered = BooleanProperty(False)
|
||
border_point = ListProperty((0, 0))
|
||
|
||
def __init__(self, **kwargs):
|
||
super().__init__(**kwargs)
|
||
self.register_event_type('on_enter')
|
||
self.register_event_type('on_leave')
|
||
Window.bind(mouse_pos=self.on_mouse_pos)
|
||
|
||
def on_mouse_pos(self, *args):
|
||
if not self.get_root_window():
|
||
return
|
||
pos = args[1]
|
||
inside = self.collide_point(*self.to_widget(*pos))
|
||
if self.hovered == inside:
|
||
return
|
||
self.border_point = pos
|
||
self.hovered = inside
|
||
if inside:
|
||
self.dispatch('on_enter')
|
||
else:
|
||
self.dispatch('on_leave')
|
||
|
||
def on_enter(self):
|
||
pass
|
||
|
||
def on_leave(self):
|
||
pass
|
||
|
||
class AnimatedButton(Button):
|
||
# Цвета для разных состояний
|
||
original_color = ListProperty([0.392, 0.416, 0.431, 1]) # Основной цвет (синий)
|
||
hover_color = ListProperty([0.165, 0.592, 1, 1]) # При наведении
|
||
press_color = ListProperty([0, 0.51, 1, 1]) # При нажатии
|
||
|
||
# Параметры анимации
|
||
hover_scale = 1.05
|
||
press_scale = 0.98
|
||
|
||
def __init__(self, **kwargs):
|
||
super().__init__(**kwargs)
|
||
self.background_normal = ''
|
||
self.background_color = self.original_color
|
||
self.original_size = self.size.copy()
|
||
self.is_hovered = False
|
||
|
||
# Настройка отслеживания мыши
|
||
Window.bind(mouse_pos=self.on_mouse_pos)
|
||
|
||
def on_mouse_pos(self, window, pos):
|
||
# Преобразуем координаты мыши в координаты кнопки
|
||
if not self.get_root_window():
|
||
return
|
||
pos = self.to_widget(*pos)
|
||
is_inside = self.collide_point(*pos)
|
||
|
||
# Обрабатываем вход/выход курсора
|
||
if is_inside and not self.is_hovered:
|
||
self.is_hovered = True
|
||
self.on_enter()
|
||
elif not is_inside and self.is_hovered:
|
||
self.is_hovered = False
|
||
self.on_leave()
|
||
|
||
def on_enter(self):
|
||
Animation.cancel_all(self)
|
||
Animation(
|
||
background_color=self.hover_color,
|
||
size=(self.original_size[0] * self.hover_scale,
|
||
self.original_size[1] * self.hover_scale),
|
||
duration=0.15,
|
||
t='out_quad'
|
||
).start(self)
|
||
|
||
def on_leave(self):
|
||
Animation.cancel_all(self)
|
||
Animation(
|
||
background_color=self.original_color,
|
||
size=self.original_size,
|
||
duration=0.2,
|
||
t='out_quad'
|
||
).start(self)
|
||
|
||
def on_touch_down(self, touch):
|
||
if self.collide_point(*touch.pos):
|
||
Animation.cancel_all(self)
|
||
Animation(
|
||
background_color=self.press_color,
|
||
size=(self.original_size[0] * self.press_scale,
|
||
self.original_size[1] * self.press_scale),
|
||
duration=0.1,
|
||
t='in_out_quad'
|
||
).start(self)
|
||
return super().on_touch_down(touch)
|
||
|
||
def on_touch_up(self, touch):
|
||
if self.collide_point(*touch.pos):
|
||
Animation.cancel_all(self)
|
||
Animation(
|
||
background_color=self.hover_color if self.is_hovered else self.original_color,
|
||
size=(self.original_size[0] * (self.hover_scale if self.is_hovered else 1),
|
||
self.original_size[1] * (self.hover_scale if self.is_hovered else 1)),
|
||
duration=0.1,
|
||
t='out_quad'
|
||
).start(self)
|
||
return super().on_touch_up(touch)
|
||
|
||
class ScrollableLabel(ScrollView):
|
||
text = StringProperty('')
|
||
|
||
def __init__(self, **kwargs):
|
||
super().__init__(**kwargs)
|
||
|
||
self.label = Label(
|
||
size_hint_y=None,
|
||
font_size=dp(18),
|
||
halign='left',
|
||
valign='top',
|
||
padding=(dp(15), dp(15)),
|
||
markup=True
|
||
)
|
||
self.label.bind(
|
||
texture_size=self._update_label_size,
|
||
width=lambda *x: setattr(self.label, 'text_size', (self.width, None)))
|
||
self.bind(
|
||
width=lambda *x: setattr(self.label, 'text_size', (self.width, None)))
|
||
self.add_widget(self.label)
|
||
|
||
def _update_label_size(self, instance, size):
|
||
instance.size = (self.width, size[1])
|
||
|
||
def on_text(self, instance, value):
|
||
self.label.text = value
|
||
|
||
class KompasApp(App):
|
||
def __init__(self, **kwargs):
|
||
super().__init__(**kwargs)
|
||
self.title = "Kompas Saver"
|
||
|
||
def build(self):
|
||
Window.size = (800, 600)
|
||
main_layout = BoxLayout(orientation='horizontal', spacing=10, padding=10)
|
||
|
||
|
||
# Левая панель (кнопки)
|
||
left_panel = BoxLayout(orientation='vertical', size_hint=(0.3, 1), spacing=10)
|
||
header = Label(text="Kompas Saver", size_hint=(1, 0.1), font_size=24, bold=True)
|
||
|
||
# Стиль для кнопок
|
||
button_style = {
|
||
'size_hint': (1, 1), #лучше не менять, т.к. кнопки будут плыть при переключении между оконным и полноэкранным режимом
|
||
'height': 150,
|
||
'halign': 'center',
|
||
'valign': 'middle',
|
||
'text_size': (None, None),
|
||
'padding': (10, 10)
|
||
}
|
||
|
||
# Создаем анимированные кнопки
|
||
button1 = AnimatedButton(text="Создать PDF", on_press=self.process_kompas, **button_style)
|
||
button2 = AnimatedButton(text="Сохранить в IGES", on_press=self.save_to_iges, **button_style)
|
||
button3 = AnimatedButton(text="Получить информацию \nо чертеже", on_press=self.get_all_sheets, **button_style)
|
||
button4 = AnimatedButton(text="Projects Support", on_press=self.project_support, **button_style)
|
||
button5 = AnimatedButton(text="Открытые файлы", on_press=self.get_opened_files, **button_style)
|
||
|
||
left_panel.add_widget(header)
|
||
left_panel.add_widget(button1)
|
||
left_panel.add_widget(button2)
|
||
left_panel.add_widget(button3)
|
||
left_panel.add_widget(button4)
|
||
left_panel.add_widget(button5)
|
||
|
||
# Правая панель (прокручиваемый текст)
|
||
self.right_panel = BoxLayout(orientation='vertical', size_hint=(0.7, 1))
|
||
self.scroll_label = ScrollableLabel()
|
||
self.right_panel.add_widget(self.scroll_label)
|
||
|
||
main_layout.add_widget(left_panel)
|
||
main_layout.add_widget(self.right_panel)
|
||
return main_layout
|
||
|
||
def update_output(self, text):
|
||
self.scroll_label.text = text
|
||
|
||
def process_kompas(self, instance):
|
||
self.update_output("Конвертация в PDF...\n")
|
||
Clock.schedule_once(lambda dt: self._run_export(), 0.2)
|
||
|
||
def _run_export(self):
|
||
try:
|
||
result = export_opened_to_raster()
|
||
self.update_output(result)
|
||
except Exception as e:
|
||
self.update_output(f"[color=ff3333]Ошибка: {str(e)}[/color]")
|
||
|
||
def save_to_iges(self, instance):
|
||
self.update_output("Экспорт в IGES...")
|
||
Clock.schedule_once(lambda dt: self._run_save_iges(), 0.2)
|
||
|
||
def _run_save_iges(self):
|
||
try:
|
||
result = save_opened_to_iges()
|
||
self.update_output(result)
|
||
except Exception as e:
|
||
self.update_output(f"[color=ff3333]Ошибка: {str(e)}[/color]")
|
||
|
||
def get_all_sheets(self, instance):
|
||
self.update_output("Получение списка листов...")
|
||
Clock.schedule_once(lambda dt: self._run_get_sheets(), 0.2)
|
||
|
||
def _run_get_sheets(self):
|
||
try:
|
||
result = get_all_sheets()
|
||
self.update_output(result)
|
||
except Exception as e:
|
||
self.update_output(f"[color=ff3333]Ошибка: {str(e)}[/color]")
|
||
|
||
def project_support(self, instance):
|
||
self.update_output("Project Support...")
|
||
Clock.schedule_once(lambda dt: self._run_project_support(), 0.2)
|
||
|
||
def _run_project_support(self):
|
||
try:
|
||
result = project_support()
|
||
self.update_output(result)
|
||
except Exception as e:
|
||
self.update_output(f"[color=ff3333]Ошибка: {str(e)}[/color]")
|
||
|
||
def get_opened_files(self, instance):
|
||
self.update_output("Получение списка открытых файлов...")
|
||
Clock.schedule_once(lambda dt: self._run_get_opened_files(), 0.2)
|
||
|
||
def _run_get_opened_files(self):
|
||
try:
|
||
result = get_opened_files()
|
||
self.update_output(result)
|
||
except Exception as e:
|
||
self.update_output(f"[color=ff3333]Ошибка: {str(e)}[/color]")
|
||
|
||
if __name__ == '__main__':
|
||
KompasApp().run() |