ursina_ui.py 18.4 KB
Newer Older
三月三net's avatar
三月三net 已提交
1 2 3 4 5 6 7 8 9
# -*- coding:utf-8 -*-
# title           :ursina天体运行模拟器UI控制
# description     :ursina天体运行模拟器UI控制
# author          :Python超人
# date            :2023-02-11
# link            :https://gitcode.net/pythoncr/
# python_version  :3.8
# ==============================================================================
from ursina import Ursina, window, Entity, Grid, Mesh, camera, Text, application, color, mouse, Vec2, Vec3, \
三月三net's avatar
三月三net 已提交
10
    load_texture, held_keys, Button, ButtonList, destroy, scene, distance, Sequence, Wait, Func
三月三net's avatar
三月三net 已提交
11
from ursina.prefabs.first_person_controller import FirstPersonController
三月三net's avatar
三月三net 已提交
12 13
from common.consts import SECONDS_PER_HOUR, SECONDS_PER_HALF_DAY, \
    SECONDS_PER_DAY, SECONDS_PER_WEEK, SECONDS_PER_MONTH, SECONDS_PER_YEAR
三月三net's avatar
三月三net 已提交
14
from common.consts import AU
三月三net's avatar
三月三net 已提交
15
from simulators.ursina.ui_component import UiSlider, SwithButton, UiButton, Buttons
三月三net's avatar
三月三net 已提交
16 17
from simulators.ursina.ursina_config import UrsinaConfig
from simulators.ursina.ursina_event import UrsinaEvent
三月三net's avatar
三月三net 已提交
18
from ursina import WindowPanel, InputField, Button, Slider, ButtonGroup, Panel, invoke
三月三net's avatar
三月三net 已提交
19 20 21 22


class UrsinaUI:

三月三net's avatar
三月三net 已提交
23
    def ui_component_init(self):
三月三net's avatar
三月三net 已提交
24

三月三net's avatar
三月三net 已提交
25 26 27 28
        self.start_button_text = "●"  # 》●▲○◎
        self.pause_button_text = "〓"  # 〓 || ‖
        self.no_trail_button_text = "○ "
        self.trail_button_text = "○--"
三月三net's avatar
三月三net 已提交
29

三月三net's avatar
三月三net 已提交
30
        # application.time_scale = 0.5
三月三net's avatar
三月三net 已提交
31
        self.slider_body_spin_factor = UiSlider(text='自转速度', min=0.01, max=30, default=1)
三月三net's avatar
三月三net 已提交
32
        self.slider_body_size_factor = UiSlider(text='天体缩放', min=0.1, max=100, step=0.1, default=1)
三月三net's avatar
三月三net 已提交
33
        self.slider_run_speed_factor = UiSlider(text="运行速度", min=0.01, max=80, default=1)
三月三net's avatar
三月三net 已提交
34
        self.slider_control_speed_factor = UiSlider(text="控制速度", min=0.01, max=20, default=application.time_scale)
三月三net's avatar
三月三net 已提交
35
        self.slider_trail_length = UiSlider(text="拖尾长度", min=30, max=500, step=10, default=UrsinaConfig.trail_length)
三月三net's avatar
三月三net 已提交
36

三月三net's avatar
三月三net 已提交
37
        self.slider_body_size_factor.on_value_changed = self.on_slider_body_size_changed
三月三net's avatar
三月三net 已提交
38 39 40
        self.slider_body_spin_factor.on_value_changed = self.on_slider_body_spin_changed
        self.slider_run_speed_factor.on_value_changed = self.on_slider_run_speed_changed
        self.slider_control_speed_factor.on_value_changed = self.on_slider_control_speed_changed
三月三net's avatar
三月三net 已提交
41 42
        self.slider_trail_length.on_value_changed = self.on_slider_trail_length_changed

三月三net's avatar
三月三net 已提交
43
        self.on_off_switch = SwithButton((self.pause_button_text,
三月三net's avatar
三月三net 已提交
44 45
                                          self.start_button_text),
                                         default=self.start_button_text,
三月三net's avatar
三月三net 已提交
46
                                         tooltips=('暂停(P)', '运行(P)'))
三月三net's avatar
三月三net 已提交
47
        self.on_off_switch.selected_color = color.red
三月三net's avatar
三月三net 已提交
48

三月三net's avatar
三月三net 已提交
49 50 51 52 53
        self.sec_per_time_switch = SwithButton(("默认", "天", "周", "月", "年", "十年", "百年"),
                                               default="默认",
                                               tooltips=("系统默认", "每秒相当于1天", "每秒相当于1周",
                                                         "每秒相当于1个月",
                                                         "每秒相当于1年", "每秒相当于十年", "每秒相当于1百年"))
三月三net's avatar
三月三net 已提交
54
        self.sec_per_time_switch.on_value_changed = self.sec_per_time_switch_changed
三月三net's avatar
三月三net 已提交
55

三月三net's avatar
三月三net 已提交
56 57 58
        self.on_off_trail = SwithButton((self.no_trail_button_text, self.trail_button_text),
                                        default=self.no_trail_button_text,
                                        tooltips=('天体运行无轨迹', '天体运行有拖尾轨迹'))
三月三net's avatar
三月三net 已提交
59 60
        self.on_off_trail.on_value_changed = self.on_off_trail_changed

三月三net's avatar
三月三net 已提交
61 62 63
        # self.buttons = Buttons(("寻找", "重启"), tooltips=("寻找天体(Y)", "重新开始(O)"))


三月三net's avatar
三月三net 已提交
64 65
        self.point_button = UiButton(text='寻找天体(Y)', on_click=self.on_searching_bodies_click)
        self.reset_button = UiButton(text='重新开始(O)', on_click=self.on_reset_button_click)
三月三net's avatar
三月三net 已提交
66

三月三net's avatar
三月三net 已提交
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
        # button1 = Button(text='Button 1', scale=(0.1, 0.1), position=(-0.1, 0))
        # button2 = Button(text='Button 2', scale=(0.1, 0.1), position=(0.1, 0))

        # btn_settings = UiButton(text='操作设置', on_click=self.on_point_button_click)
        # btn_settings.position = window.top_left
        # btn_settings.y = 0.5
        # # btn_settings.scale = (0.1,0.1)
        # # btn_settings.y = 0
        # btn_settings.scale = (.25, .025),
        # btn_settings.origin = (-.5, .5),
        # btn_settings.pressed_scale = 1,
        # if btn_settings.text_entity:
        #     btn_settings.text_entity.x = .05
        #     btn_settings.text_entity.origin = (-.5, 0)
        #     btn_settings.text_entity.scale *= .8
三月三net's avatar
三月三net 已提交
82 83

        self.on_off_switch.on_value_changed = self.on_off_switch_changed
三月三net's avatar
三月三net 已提交
84 85 86 87 88 89 90
        wp = WindowPanel(
            title='',
            content=(
                # InputField(name='name_field'),
                # Button(text='Submit', color=color.azure),
                self.point_button,
                self.reset_button,
三月三net's avatar
三月三net 已提交
91
                # self.buttons,
三月三net's avatar
三月三net 已提交
92
                self.sec_per_time_switch,
三月三net's avatar
三月三net 已提交
93
                self.on_off_switch,
三月三net's avatar
三月三net 已提交
94 95
                self.on_off_trail,
                self.slider_trail_length,
三月三net's avatar
三月三net 已提交
96
                self.slider_body_size_factor,
三月三net's avatar
三月三net 已提交
97 98 99 100
                self.slider_body_spin_factor,
                self.slider_run_speed_factor,
                self.slider_control_speed_factor

三月三net's avatar
三月三net 已提交
101
            ), ignore_paused=True, color=color.rgba(0.0, 0.0, 0.0, 0.5)  # , popup=True
三月三net's avatar
三月三net 已提交
102
        )
三月三net's avatar
三月三net 已提交
103 104
        self.sec_per_time_switch.x = -0.4
        self.on_off_switch.x = 0.2
三月三net's avatar
三月三net 已提交
105
        self.on_off_trail.x = 0.2  # -0.4
三月三net's avatar
三月三net 已提交
106
        wp.y = 0.5  # wp.panel.scale_y / 2 * wp.scale_y  # center the window panel
三月三net's avatar
三月三net 已提交
107
        wp.x = 0.6  # wp.scale_x + 0.1
三月三net's avatar
三月三net 已提交
108
        # wp.x = 0#wp.panel.scale_x / 2 * wp.scale_x
三月三net's avatar
三月三net 已提交
109
        self.wp = wp
三月三net's avatar
三月三net 已提交
110
        self.wp.enabled = False
三月三net's avatar
三月三net 已提交
111

三月三net's avatar
三月三net 已提交
112 113 114
    def __init__(self):
        self.ui_component_init()

三月三net's avatar
三月三net 已提交
115
        self.settings_handler = Entity(ignore_paused=True)
三月三net's avatar
三月三net 已提交
116 117 118 119
        # 加载中文字体文件

        # text_time_scale = "1"
        # self.text_time_scale_info = None
三月三net's avatar
三月三net 已提交
120
        self.settings_handler.input = self.settings_handler_input
三月三net's avatar
三月三net 已提交
121
        # self.show_text_time_scale_info()
三月三net's avatar
三月三net 已提交
122 123 124
        # Text('方位控制: Q W E A S D + 鼠标右键', font='msyhl.ttc'),
        key_info_str = "方位控制[键盘QWEASD]+[鼠标右键],按[空格]更多控制"
        key_info = Text(text=key_info_str, font=UrsinaConfig.CN_FONT, position=(-1, 0.5), origin=(-1, 1),
三月三net's avatar
三月三net 已提交
125
                        background=True)
三月三net's avatar
三月三net 已提交
126 127 128 129
        # # self.show_button()
        # slider_text = Text(text='自转速度', scale=1, position=(-0.6, 0.3))
        # slider = Slider(scale=0.5, position=(-0.6, 0), min=0, max=10, step=1, text=slider_text)

三月三net's avatar
三月三net 已提交
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
    def show_message(self, message, close_time=3):
        """
        创建消息框
        :param message: 消息内容
        :param close_time: 定义关闭时间
        :return:
        """
        # 创建消息框
        message_box = Text(text=message, font=UrsinaConfig.CN_FONT, background=True, origin=(0, 0), y=.25)

        # 定义关闭函数
        def close_message():
            destroy(message_box)

        s = Sequence(
三月三net's avatar
三月三net 已提交
145
            Wait(close_time),
三月三net's avatar
三月三net 已提交
146 147 148 149 150 151
            Func(close_message)
        )
        s.start()
        # # 使用 time 模块来实现定时关闭
        # invoke(close_message, delay=close_time)

三月三net's avatar
三月三net 已提交
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
    def sec_per_time_switch_changed(self):
        # ("默认", "天", "周", "月", "年", "十年", "百年")
        if self.sec_per_time_switch.value == "天":
            UrsinaConfig.seconds_per = SECONDS_PER_DAY
        elif self.sec_per_time_switch.value == "周":
            UrsinaConfig.seconds_per = SECONDS_PER_WEEK
        elif self.sec_per_time_switch.value == "月":
            UrsinaConfig.seconds_per = SECONDS_PER_MONTH
        elif self.sec_per_time_switch.value == "年":
            UrsinaConfig.seconds_per = SECONDS_PER_YEAR
        elif self.sec_per_time_switch.value == "十年":
            UrsinaConfig.seconds_per = SECONDS_PER_YEAR * 10
        elif self.sec_per_time_switch.value == "百年":
            UrsinaConfig.seconds_per = SECONDS_PER_YEAR * 100
        else:
            UrsinaConfig.seconds_per = 0

三月三net's avatar
三月三net 已提交
169
    def on_off_trail_changed(self):
三月三net's avatar
三月三net 已提交
170
        if self.on_off_trail.value == self.trail_button_text:
三月三net's avatar
三月三net 已提交
171 172 173 174
            UrsinaConfig.show_trail = True
        else:
            UrsinaConfig.show_trail = False

三月三net's avatar
三月三net 已提交
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
    def move_camera_to_entity(self, camera_pos: Vec3, entity_pos: Vec3, _distance: float) -> Vec3:
        # 计算摄像机到实体的向量
        direction = entity_pos - camera_pos
        # 计算当前距离
        current_distance = direction.length()
        # 如果当前距离已经小于等于要求的距离,则直接返回实体坐标
        if current_distance <= _distance:
            return camera_pos
        # 计算需要移动的距离
        _distance = current_distance - _distance
        # 根据需要移动的距离计算移动向量
        move_vector = direction.normalized() * _distance
        # 返回摄像机移动后的坐标
        return camera_pos + move_vector

三月三net's avatar
三月三net 已提交
190
    def move_camera_to_entity(self, entity, d):
三月三net's avatar
三月三net 已提交
191 192
        import math
        # print("before",camera.position, entity.position)
三月三net's avatar
三月三net 已提交
193
        camera.position = entity.position  # - Vec3(0, 0, d)  # 设置摄像机位置
三月三net's avatar
三月三net 已提交
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
        camera.world_position = entity.position
        # camera.rotation = (0, 0, 0)  # 重置摄像机旋转角度

        # print("after",camera.position,entity.position)

        # # 获取相机和实体之间的向量
        # target_vector = entity.position - camera.position
        # target_vector.y = 0  # 假设实体在 x-z 平面上,将 y 坐标设为 0
        #
        # # 计算旋转角度
        # angle = math.degrees(math.atan2(target_vector.z, target_vector.x))
        # camera.rotation_y = angle  # 旋转相机

        # camera.look_at(entity.position)  # 对准指定实体

三月三net's avatar
三月三net 已提交
209
    def bodies_button_list_click(self, item):
三月三net's avatar
三月三net 已提交
210
        if item is not None:
三月三net's avatar
三月三net 已提交
211 212 213
            # TODO: 先找到位置,确定摄像机的位置
            # print("select->", item)
            # UrsinaConfig.SCALE_FACTOR
三月三net's avatar
三月三net 已提交
214 215
            # import copy
            # camera_rotation = copy.deepcopy(camera.rotation)
三月三net's avatar
三月三net 已提交
216 217 218 219 220
            try:
                d = item.planet.scale_x * 20
                self.move_camera_to_entity(item.planet, d)
            except Exception as e:
                self.show_message(f"{item}飞不见了")
三月三net's avatar
三月三net 已提交
221 222 223 224 225 226 227 228
            # d = distance(camera.position, item.planet.position)
            # camera.look_at(item.planet)
            # if d > 1.5 * x:
            #     move_to = self.move_camera_to_entity(camera.position, item.planet.position, x)
            #     camera.position = move_to

            # camera_rotation = copy.deepcopy(camera.rotation)
            # camera.rotation = (camera_rotation[0], camera_rotation[1], 0)
三月三net's avatar
三月三net 已提交
229
            # camera.forward = (1, 0, 0)  # 设置相机的方向向量为x轴方向
三月三net's avatar
三月三net 已提交
230
        self.bodies_button_list_close()
三月三net's avatar
三月三net 已提交
231

三月三net's avatar
三月三net 已提交
232 233 234 235 236 237 238 239 240 241
    # my_entity = Entity(model='cube', color=color.red, position=(0, 1, 5))
    #
    # # 获取当前摄像机
    # camera = scene.camera
    #
    # # 计算 Entity 和摄像机之间的距离
    # distance_to_entity = distance(my_entity, camera)
    #
    # print('距离:', distance_to_entity)

三月三net's avatar
三月三net 已提交
242 243 244 245 246
    def bodies_button_list_close(self):
        if hasattr(self, "bodies_button_list"):
            self.bodies_button_list.enabled = False
            destroy(self.bodies_button_list)

三月三net's avatar
三月三net 已提交
247 248 249 250
    def on_searching_bodies_click(self):
        results = UrsinaEvent.on_searching_bodies()
        if len(results) > 0:
            sub_name, bodies = results[0]
三月三net's avatar
三月三net 已提交
251 252 253 254
            if len(bodies) == 0:
                self.show_message("天体都飞不见了,请重新运行。")
                # button_dict = {"天体都飞不见了,请重新运行。": lambda: self.bodies_button_list_click(None)}
                return
三月三net's avatar
三月三net 已提交
255
            # print(results[0])
三月三net's avatar
三月三net 已提交
256
            button_dict = {"[关闭]        == 寻找天体 ==": lambda: self.bodies_button_list_click(None)}
三月三net's avatar
三月三net 已提交
257
            camera = scene.camera
三月三net's avatar
三月三net 已提交
258 259 260 261
            for body in bodies:
                def callback_action(b=body):
                    self.bodies_button_list_click(b)

三月三net's avatar
三月三net 已提交
262 263 264 265 266 267
                if body.appeared:
                    distance_to_entity = distance(body.planet, camera)
                    d = distance_to_entity / UrsinaConfig.SCALE_FACTOR / AU
                    name = f"{body.name}\t距离:{d:.4f}天文单位"
                    button_dict[name] = callback_action
                else:
三月三net's avatar
三月三net 已提交
268
                    if hasattr(self, "bodies_button_list"):
三月三net's avatar
三月三net 已提交
269
                        self.bodies_button_list_close()
三月三net's avatar
三月三net 已提交
270 271
                    name = f"{body.name}\t距离太远,找不到了"
                    button_dict[name] = lambda: self.bodies_button_list_click(None)
三月三net's avatar
三月三net 已提交
272

三月三net's avatar
三月三net 已提交
273
            if hasattr(self, "bodies_button_list"):
三月三net's avatar
三月三net 已提交
274
                self.bodies_button_list_close()
三月三net's avatar
三月三net 已提交
275

三月三net's avatar
三月三net 已提交
276 277
            self.bodies_button_list = ButtonList(button_dict, font=UrsinaConfig.CN_FONT, button_height=1.5)
            # self.bodies_button_list.input = self.bodies_button_list_input
三月三net's avatar
三月三net 已提交
278 279 280 281

    def on_reset_button_click(self):
        UrsinaEvent.on_reset()

三月三net's avatar
三月三net 已提交
282 283 284 285 286 287
    def on_buttons_changed(self):
        if self.buttons.value == "寻找":
            self.on_searching_bodies_click()
        elif self.buttons.value == "重启":
            self.on_reset_button_click()

三月三net's avatar
三月三net 已提交
288
    def on_off_switch_changed(self):
三月三net's avatar
三月三net 已提交
289
        if self.on_off_switch.value == self.pause_button_text:
三月三net's avatar
三月三net 已提交
290 291
            self.on_off_switch.selected_color = color.green
            application.paused = True
三月三net's avatar
三月三net 已提交
292 293 294 295
            for c in self.wp.children:
                if not c.ignore_paused:
                    # c.enabled = True
                    c.disabled = False
三月三net's avatar
三月三net 已提交
296 297 298
        else:
            self.on_off_switch.selected_color = color.red
            application.paused = False
三月三net's avatar
三月三net 已提交
299 300 301 302
            for c in self.wp.children:
                if not c.ignore_paused:
                    # c.enabled = True
                    c.disabled = False
三月三net's avatar
三月三net 已提交
303

三月三net's avatar
三月三net 已提交
304 305 306
    def on_slider_trail_length_changed(self):
        UrsinaConfig.trail_length = int(self.slider_trail_length.value)

三月三net's avatar
三月三net 已提交
307 308 309 310 311 312
    def on_slider_control_speed_changed(self):
        application.time_scale = self.slider_control_speed_factor.value

    def on_slider_body_spin_changed(self):
        UrsinaConfig.body_spin_factor = self.slider_body_spin_factor.value

三月三net's avatar
三月三net 已提交
313 314 315
    def on_slider_body_size_changed(self):
        UrsinaConfig.body_size_factor = self.slider_body_size_factor.value

三月三net's avatar
三月三net 已提交
316 317 318
    def on_slider_run_speed_changed(self):
        UrsinaConfig.run_speed_factor = self.slider_run_speed_factor.value

三月三net's avatar
三月三net 已提交
319 320 321 322 323
    # def show_text_time_scale_info(self):
    #     if self.text_time_scale_info is not None:
    #         self.text_time_scale_info.disable()
    #     text_time_scale = "控制倍率:" + str(application.time_scale).ljust(4, " ")
    #     text_time_scale_info = Text(text=text_time_scale, position=(-0.8, 0.5), origin=(-1, 1), background=True)
三月三net's avatar
三月三net 已提交
324

三月三net's avatar
三月三net 已提交
325 326
    # def show_button(self):
    #     b = Button(scale=(0, .25), text='zzz')
三月三net's avatar
三月三net 已提交
327 328 329 330 331 332 333 334

    #  if key == "escape":
    #             if mouse.locked:
    #                 self.on_disable()
    #             else:
    #                 sys.exit()

    # 按空格键则暂停
三月三net's avatar
三月三net 已提交
335
    def settings_handler_input(self, key):
三月三net's avatar
三月三net 已提交
336 337 338 339 340
        import sys
        if key == "escape":
            sys.exit()
        # print(key)
        elif key == 'space':
三月三net's avatar
三月三net 已提交
341
            self.wp.enabled = not self.wp.enabled
三月三net's avatar
三月三net 已提交
342 343
        elif key == 'left mouse down':
            print(key)
三月三net's avatar
三月三net 已提交
344 345 346
        elif key == 'y':  # 寻找天体
            if hasattr(self, "bodies_button_list"):
                if self.bodies_button_list.enabled:
三月三net's avatar
三月三net 已提交
347
                    self.bodies_button_list_close()
三月三net's avatar
三月三net 已提交
348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376
                    return
            self.on_searching_bodies_click()
        elif key == 'o':  # 重新开始
            self.on_reset_button_click()
        elif key == 'i':  # 拖尾开关
            if self.on_off_trail.value == self.trail_button_text:
                self.on_off_trail.value = self.no_trail_button_text
            else:
                self.on_off_trail.value = self.trail_button_text
            self.on_off_trail_changed()
        elif key == 'p':  # 开始、暂停
            if self.on_off_switch.value == self.pause_button_text:
                self.on_off_switch.value = self.start_button_text
            else:
                self.on_off_switch.value = self.pause_button_text
            self.on_off_switch_changed()
        elif key == '+' or key == "= up":
            run_speed_factor = self.slider_run_speed_factor.value + self.slider_run_speed_factor.step * 50
            if run_speed_factor > self.slider_run_speed_factor.max:
                run_speed_factor = self.slider_run_speed_factor.max
            self.slider_run_speed_factor.value = run_speed_factor
            self.slider_run_speed_factor.knob.drop()
        elif key == '-' or key == "- up":
            run_speed_factor = self.slider_run_speed_factor.value - self.slider_run_speed_factor.step * 50
            if run_speed_factor < self.slider_run_speed_factor.min:
                run_speed_factor = self.slider_run_speed_factor.min
            self.slider_run_speed_factor.value = run_speed_factor
            self.slider_run_speed_factor.knob.drop()
    #     UrsinaConfig.run_speed_factor *= 2
三月三net's avatar
三月三net 已提交
377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406
    #     application.paused = not application.paused  # Pause/unpause the game.
    # elif key == 'tab':
    #     # application.time_scale 属性控制游戏时间流逝的速度。
    #     # 具体来说,它是一个浮点数,用于调整游戏时间流逝速度的比例,其默认值为 1.0,表示正常速度。
    #     # 当你将它设置为小于 1.0 的值时,游戏时间会变慢,而设置为大于 1.0 的值时,游戏时间则会变快。
    #     for idx, time_scale in enumerate(time_scales):
    #         if float(application.time_scale) == time_scale:
    #             if idx < len(time_scales) - 1:
    #                 application.time_scale = time_scales[idx + 1]
    #                 break
    #             else:
    #                 application.time_scale = time_scales[0]
    # elif key == '+':
    #     UrsinaConfig.run_speed_factor *= 2
    # elif key == "= up":
    #     UrsinaConfig.body_spin_factor *= 2
    #     # if application.time_scale in time_scales:
    #     #     idx = time_scales.index(application.time_scale)
    #     #     if idx < len(time_scales) - 1:
    #     #         application.time_scale = time_scales[idx + 1]
    # elif key == '-':
    #     UrsinaConfig.run_speed_factor *= 0.5
    # elif key == "- up":
    #     UrsinaConfig.body_spin_factor *= 0.5
    #     # if application.time_scale in time_scales:
    #     #     idx = time_scales.index(application.time_scale)
    #     #     if idx > 0:
    #     #         application.time_scale = time_scales[idx - 1]
    #
    # self.show_text_time_scale_info()