From 7120c424d4aa24ab63158faef9989ca80aa8704a Mon Sep 17 00:00:00 2001 From: alfrix Date: Wed, 7 Dec 2022 11:44:21 -0300 Subject: [PATCH] gtk: resizability doesn't rescale the fonts or images --- ks_includes/KlippyGtk.py | 59 +++++++++++----------------------- ks_includes/screen_panel.py | 2 -- panels/base_panel.py | 10 ++---- panels/bed_mesh.py | 4 +-- panels/exclude.py | 6 ++-- panels/extrude.py | 4 +-- panels/gcode_macros.py | 4 +-- panels/job_status.py | 6 ++-- panels/main_menu.py | 6 ++-- panels/move.py | 4 +-- panels/network.py | 1 - panels/power.py | 4 +-- panels/splash_screen.py | 4 +-- panels/temperature.py | 6 ++-- screen.py | 64 ++++++++++++++++++------------------- styles/base.css | 22 +++++++++++-- 16 files changed, 96 insertions(+), 110 deletions(-) diff --git a/ks_includes/KlippyGtk.py b/ks_includes/KlippyGtk.py index 3da3e316..67059b1c 100644 --- a/ks_includes/KlippyGtk.py +++ b/ks_includes/KlippyGtk.py @@ -27,44 +27,52 @@ def format_label(widget, lines=2): class KlippyGtk: labels = {} - def __init__(self, screen, width, height, theme, cursor, fontsize_type): + def __init__(self, screen): self.screen = screen - self.width = width - self.height = height - self.themedir = os.path.join(pathlib.Path(__file__).parent.resolve().parent, "styles", theme, "images") - self.cursor = cursor - self.font_size_type = fontsize_type + self.themedir = os.path.join(pathlib.Path(__file__).parent.resolve().parent, "styles", screen.theme, "images") + self.cursor = screen.show_cursor + self.font_size_type = screen._config.get_main_config().get("font_size", "medium") + self.width = screen.width + self.height = screen.height self.font_ratio = [33, 49] if self.screen.vertical_mode else [43, 29] self.font_size = min(self.width / self.font_ratio[0], self.height / self.font_ratio[1]) self.img_scale = self.font_size * 2 self.button_image_scale = 1.38 self.bsidescale = .65 # Buttons with image at the side - if fontsize_type == "max": + if self.font_size_type == "max": self.font_size = self.font_size * 1.2 self.bsidescale = .7 - elif fontsize_type == "extralarge": + elif self.font_size_type == "extralarge": self.font_size = self.font_size * 1.14 self.img_scale = self.img_scale * 0.7 self.bsidescale = 1 - elif fontsize_type == "large": + elif self.font_size_type == "large": self.font_size = self.font_size * 1.09 self.img_scale = self.img_scale * 0.9 self.bsidescale = .8 - elif fontsize_type == "small": + elif self.font_size_type == "small": self.font_size = self.font_size * 0.91 self.bsidescale = .55 self.img_width = self.font_size * 3 self.img_height = self.font_size * 3 self.titlebar_height = self.font_size * 2 - logging.info(f"Font size: {self.font_size} ({fontsize_type})") + logging.info(f"Font size: {self.font_size:.1f} ({self.font_size_type})") if self.screen.vertical_mode: self.action_bar_width = int(self.width) self.action_bar_height = int(self.height * .1) + self.content_width = self.width + self.content_height = self.height - self.titlebar_height - self.action_bar_height else: self.action_bar_width = int(self.width * .1) self.action_bar_height = int(self.height) + self.content_width = self.width - self.action_bar_width + self.content_height = self.height - self.titlebar_height + + self.keyboard_height = self.content_height * 0.5 + if (self.height / self.width) >= 3: # Ultra-tall + self.keyboard_height = self.keyboard_height * 0.5 self.color_list = {} # This is set by screen.py init_style() for key in self.color_list: @@ -72,35 +80,6 @@ class KlippyGtk: rgb = [int(self.color_list[key]['base'][i:i + 2], 16) for i in range(0, 6, 2)] self.color_list[key]['rgb'] = rgb - def get_action_bar_width(self): - return self.action_bar_width - - def get_action_bar_height(self): - return self.action_bar_height - - def get_content_width(self): - if self.screen.vertical_mode: - return self.width - return self.width - self.action_bar_width - - def get_content_height(self): - if self.screen.vertical_mode: - return self.height - self.titlebar_height - self.action_bar_height - return self.height - self.titlebar_height - - def get_font_size(self): - return self.font_size - - def get_titlebar_height(self): - return self.titlebar_height - - def get_keyboard_height(self): - if (self.height / self.width) >= 3: - # Ultra-tall - return self.get_content_height() * 0.25 - else: - return self.get_content_height() * 0.5 - def get_temp_color(self, device): # logging.debug("Color list %s" % self.color_list) if device not in self.color_list: diff --git a/ks_includes/screen_panel.py b/ks_includes/screen_panel.py index 31db17b4..b51dfe82 100644 --- a/ks_includes/screen_panel.py +++ b/ks_includes/screen_panel.py @@ -26,8 +26,6 @@ class ScreenPanel: self.title = title self.devices = {} self.active_heaters = [] - self.layout = Gtk.Layout() - self.layout.set_size(screen.width, screen.height) self.content = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.content.get_style_context().add_class("content") self.content.set_hexpand(True) diff --git a/panels/base_panel.py b/panels/base_panel.py index ac6f609a..a0eba4c1 100644 --- a/panels/base_panel.py +++ b/panels/base_panel.py @@ -59,9 +59,8 @@ class BasePanel(ScreenPanel): else: self.action_bar.set_hexpand(False) self.action_bar.set_vexpand(True) - self.action_bar.set_size_request(self._gtk.get_action_bar_width(), self._gtk.get_action_bar_height()) - self.action_bar.get_style_context().add_class('action_bar') + self.action_bar.set_size_request(self._gtk.action_bar_width, self._gtk.action_bar_height) self.action_bar.add(self.control['back']) self.action_bar.add(self.control['home']) self.show_back(False) @@ -88,7 +87,7 @@ class BasePanel(ScreenPanel): self.control['time_box'].pack_end(self.control['time'], True, True, 10) self.titlebar = Gtk.Box(spacing=5) - self.titlebar.set_size_request(self._gtk.get_content_width(), self._gtk.get_titlebar_height()) + self.titlebar.get_style_context().add_class("title_bar") self.titlebar.set_valign(Gtk.Align.CENTER) self.titlebar.add(self.control['temp_box']) self.titlebar.add(self.titlelbl) @@ -96,9 +95,6 @@ class BasePanel(ScreenPanel): # Main layout self.main_grid = Gtk.Grid() - # To achieve rezisability this needs to be removed - # The main issue is that currently the content doesn't expand correctly - self.main_grid.set_size_request(self._screen.width, self._screen.height) if self._screen.vertical_mode: self.main_grid.attach(self.titlebar, 0, 0, 1, 1) @@ -111,8 +107,6 @@ class BasePanel(ScreenPanel): self.main_grid.attach(self.titlebar, 1, 0, 1, 1) self.main_grid.attach(self.content, 1, 1, 1, 1) - # Layout is and content are on screen_panel - self.layout.add(self.main_grid) self.update_time() def show_heaters(self, show=True): diff --git a/panels/bed_mesh.py b/panels/bed_mesh.py index e34b3642..66df3335 100644 --- a/panels/bed_mesh.py +++ b/panels/bed_mesh.py @@ -54,11 +54,11 @@ class BedMeshPanel(ScreenPanel): grid = self._gtk.HomogeneousGrid() grid.set_row_homogeneous(False) grid.attach(topbar, 0, 0, 2, 1) - self.labels['map'] = BedMap(self._gtk.get_font_size(), self.active_mesh) + self.labels['map'] = BedMap(self._gtk.font_size, self.active_mesh) if self._screen.vertical_mode: grid.attach(self.labels['map'], 0, 2, 2, 1) grid.attach(scroll, 0, 3, 2, 1) - self.labels['map'].set_size_request(self._gtk.get_content_width(), self._gtk.get_content_height() * .4) + self.labels['map'].set_size_request(self._gtk.content_width, self._gtk.content_height * .4) else: grid.attach(self.labels['map'], 0, 2, 1, 1) grid.attach(scroll, 1, 2, 1, 1) diff --git a/panels/exclude.py b/panels/exclude.py index 545479d5..c2a0e18d 100644 --- a/panels/exclude.py +++ b/panels/exclude.py @@ -43,18 +43,18 @@ class ExcludeObjectPanel(ScreenPanel): grid.attach(Gtk.Separator(), 0, 1, 2, 1) if self.objects and "polygon" in self.objects[0]: - self.labels['map'] = ObjectMap(self._screen, self._printer, self._gtk.get_font_size()) + self.labels['map'] = ObjectMap(self._screen, self._printer, self._gtk.font_size) if self._screen.vertical_mode: grid.attach(self.labels['map'], 0, 2, 2, 1) grid.attach(scroll, 0, 3, 2, 1) - scroll.set_size_request(self._gtk.get_content_width(), -1) + scroll.set_size_request(self._gtk.content_width, -1) else: grid.attach(self.labels['map'], 0, 2, 1, 1) grid.attach(scroll, 1, 2, 1, 1) scroll.set_size_request((self._screen.width * .9) // 2, -1) else: grid.attach(scroll, 0, 2, 2, 1) - scroll.set_size_request(self._gtk.get_content_width(), -1) + scroll.set_size_request(self._gtk.content_width, -1) self.content.add(grid) self.content.show_all() diff --git a/panels/extrude.py b/panels/extrude.py index f6b40cf6..85bffea5 100644 --- a/panels/extrude.py +++ b/panels/extrude.py @@ -134,8 +134,8 @@ class ExtrudePanel(ScreenPanel): self.labels[x]['label'].set_halign(Gtk.Align.CENTER) self.labels[x]['label'].set_hexpand(True) self.labels[x]['label'].set_ellipsize(Pango.EllipsizeMode.END) - self.labels[x]['switch'].set_property("width-request", round(self._gtk.get_font_size() * 2)) - self.labels[x]['switch'].set_property("height-request", round(self._gtk.get_font_size())) + self.labels[x]['switch'].set_property("width-request", round(self._gtk.font_size * 2)) + self.labels[x]['switch'].set_property("height-request", round(self._gtk.font_size)) self.labels[x]['switch'].connect("notify::active", self.enable_disable_fs, name, x) self.labels[x]['box'].pack_start(self.labels[x]['label'], True, True, 5) self.labels[x]['box'].pack_start(self.labels[x]['switch'], False, False, 5) diff --git a/panels/gcode_macros.py b/panels/gcode_macros.py index c8e12edd..d497ddb7 100644 --- a/panels/gcode_macros.py +++ b/panels/gcode_macros.py @@ -165,8 +165,8 @@ class MacroPanel(ScreenPanel): switch.set_vexpand(False) switch.set_active(self._config.get_config().getboolean(option['section'], opt_name, fallback=True)) switch.connect("notify::active", self.switch_config_option, option['section'], opt_name) - switch.set_property("width-request", round(self._gtk.get_font_size() * 7)) - switch.set_property("height-request", round(self._gtk.get_font_size() * 3.5)) + switch.set_property("width-request", round(self._gtk.font_size * 7)) + switch.set_property("height-request", round(self._gtk.font_size * 3.5)) box.add(switch) dev = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5) diff --git a/panels/job_status.py b/panels/job_status.py index b02bc819..de24c2f9 100644 --- a/panels/job_status.py +++ b/panels/job_status.py @@ -340,7 +340,7 @@ class JobStatusPanel(ScreenPanel): r = min(w, h) * .42 ctx.set_source_rgb(0.13, 0.13, 0.13) - ctx.set_line_width(self._gtk.get_font_size() * .75) + ctx.set_line_width(self._gtk.font_size * .75) ctx.translate(w / 2, h / 2) ctx.arc(0, 0, r, 0, 2 * pi) ctx.stroke() @@ -773,7 +773,7 @@ class JobStatusPanel(ScreenPanel): height = self._screen.height / 4 else: width = self._screen.width / 3 - height = self._gtk.get_content_height() * 0.47 + height = self._gtk.content_height * 0.47 pixbuf = self.get_file_image(self.filename, width, height) if pixbuf is not None: self.labels['thumbnail'].set_from_pixbuf(pixbuf) @@ -785,7 +785,7 @@ class JobStatusPanel(ScreenPanel): "complete": self.labels['file'].get_label(), "current": self.labels['file'].get_label(), "position": 0, - "limit": (self._screen.width * 37 / 480) // (self._gtk.get_font_size() / 11), + "limit": (self._screen.width * 37 / 480) // (self._gtk.font_size / 11), "length": len(self.labels['file'].get_label()) } if self.animation_timeout is None and (self.filename_label['length'] - self.filename_label['limit']) > 0: diff --git a/panels/main_menu.py b/panels/main_menu.py index 7f223995..f5ba0630 100644 --- a/panels/main_menu.py +++ b/panels/main_menu.py @@ -47,7 +47,7 @@ class MainPanel(MenuPanel): grid.attach(self.labels['menu'], 1, 0, 1, 1) self.grid = grid self.content.add(self.grid) - self.layout.show_all() + self.show_all() def update_graph_visibility(self): if self.left_panel is None or not self._printer.get_temp_store_devices(): @@ -209,12 +209,12 @@ class MainPanel(MenuPanel): name = Gtk.Label("") temp = Gtk.Label(_("Temp (°C)")) - temp.set_size_request(self._gtk.font_size * 6, -1) + temp.get_style_context().add_class("heater-grid-temp") self.labels['devices'].attach(name, 0, 0, 1, 1) self.labels['devices'].attach(temp, 1, 0, 1, 1) - self.labels['da'] = HeaterGraph(self._printer, self._gtk.get_font_size()) + self.labels['da'] = HeaterGraph(self._printer, self._gtk.font_size) self.labels['da'].set_vexpand(True) scroll = self._gtk.ScrolledWindow() diff --git a/panels/move.py b/panels/move.py index 97f322ba..659a33b5 100644 --- a/panels/move.py +++ b/panels/move.py @@ -233,8 +233,8 @@ class MovePanel(ScreenPanel): switch.set_vexpand(False) switch.set_active(self._config.get_config().getboolean(option['section'], opt_name)) switch.connect("notify::active", self.switch_config_option, option['section'], opt_name) - switch.set_property("width-request", round(self._gtk.get_font_size() * 7)) - switch.set_property("height-request", round(self._gtk.get_font_size() * 3.5)) + switch.set_property("width-request", round(self._gtk.font_size * 7)) + switch.set_property("height-request", round(self._gtk.font_size * 3.5)) box.add(switch) dev.add(box) elif option['type'] == "scale": diff --git a/panels/network.py b/panels/network.py index 3b760c5e..79103624 100644 --- a/panels/network.py +++ b/panels/network.py @@ -166,7 +166,6 @@ class NetworkPanel(ScreenPanel): delete = self._gtk.Button("delete", style="color3") delete.connect("clicked", self.remove_wifi_network, ssid) - delete.set_size_request(60, 0) delete.set_hexpand(False) delete.set_halign(Gtk.Align.END) diff --git a/panels/power.py b/panels/power.py index 4f8e31ce..646ac492 100644 --- a/panels/power.py +++ b/panels/power.py @@ -51,8 +51,8 @@ class PowerPanel(ScreenPanel): switch.set_hexpand(False) switch.set_active(self._screen.printer.get_power_device_status(device) == "on") switch.connect("notify::active", self.on_switch, device) - switch.set_property("width-request", round(self._gtk.get_font_size() * 7)) - switch.set_property("height-request", round(self._gtk.get_font_size() * 3.5)) + switch.set_property("width-request", round(self._gtk.font_size * 7)) + switch.set_property("height-request", round(self._gtk.font_size * 3.5)) labels = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) labels.add(name) diff --git a/panels/splash_screen.py b/panels/splash_screen.py index 32669d88..043ced35 100644 --- a/panels/splash_screen.py +++ b/panels/splash_screen.py @@ -17,7 +17,7 @@ class SplashScreenPanel(ScreenPanel): def __init__(self, screen, title): super().__init__(screen, title) - image = self._gtk.Image("klipper", self._gtk.get_content_width() * .2, self._gtk.get_content_height() * .5) + image = self._gtk.Image("klipper", self._gtk.content_width * .2, self._gtk.content_height * .5) self.labels['text'] = Gtk.Label(_("Initializing printer...")) self.labels['text'].set_line_wrap(True) self.labels['text'].set_line_wrap_mode(Pango.WrapMode.WORD_CHAR) @@ -42,7 +42,7 @@ class SplashScreenPanel(ScreenPanel): self.labels['actions'].set_vexpand(False) self.labels['actions'].set_halign(Gtk.Align.CENTER) self.labels['actions'].set_homogeneous(True) - self.labels['actions'].set_size_request(self._gtk.get_content_width(), -1) + self.labels['actions'].set_size_request(self._gtk.content_width, -1) scroll = self._gtk.ScrolledWindow() scroll.set_hexpand(True) diff --git a/panels/temperature.py b/panels/temperature.py index a164cc08..7494e866 100644 --- a/panels/temperature.py +++ b/panels/temperature.py @@ -64,7 +64,7 @@ class TemperaturePanel(ScreenPanel): self.grid.attach(self.create_right_panel(), 1, 0, 1, 1) self.content.add(self.grid) - self.layout.show_all() + self.show_all() def create_right_panel(self): cooldown = self._gtk.Button('cool-down', _('Cooldown'), "color4", self.bts, Gtk.PositionType.LEFT, 1) @@ -428,12 +428,12 @@ class TemperaturePanel(ScreenPanel): name = Gtk.Label("") temp = Gtk.Label(_("Temp (°C)")) - temp.set_size_request(self._gtk.font_size * 6, -1) + temp.get_style_context().add_class("heater-grid-temp") self.labels['devices'].attach(name, 0, 0, 1, 1) self.labels['devices'].attach(temp, 1, 0, 1, 1) - self.labels['da'] = HeaterGraph(self._printer, self._gtk.get_font_size()) + self.labels['da'] = HeaterGraph(self._printer, self._gtk.font_size) self.labels['da'].set_vexpand(True) scroll = self._gtk.ScrolledWindow() diff --git a/screen.py b/screen.py index a88c1257..57fd57a5 100755 --- a/screen.py +++ b/screen.py @@ -110,6 +110,7 @@ class KlipperScreen(Gtk.Window): self.lang_ltr = set_text_direction(self._config.get_main_config().get("language", None)) self.connect("key-press-event", self._key_press_event) + self.connect("configure_event", self.update_size) monitor = Gdk.Display.get_default().get_primary_monitor() if monitor is None: monitor = Gdk.Display.get_default().get_monitor(0) @@ -118,22 +119,21 @@ class KlipperScreen(Gtk.Window): self.width = self._config.get_main_config().getint("width", monitor.get_geometry().width) self.height = self._config.get_main_config().getint("height", monitor.get_geometry().height) self.set_default_size(self.width, self.height) - self.set_resizable(False) + self.set_resizable(True) if not (self._config.get_main_config().get("width") or self._config.get_main_config().get("height")): self.fullscreen() self.vertical_mode = self.width < self.height logging.info(f"Screen resolution: {self.width}x{self.height}") self.theme = self._config.get_main_config().get('theme') - show_cursor = self._config.get_main_config().getboolean("show_cursor", fallback=False) - self.gtk = KlippyGtk(self, self.width, self.height, self.theme, show_cursor, - self._config.get_main_config().get("font_size", "medium")) + self.show_cursor = self._config.get_main_config().getboolean("show_cursor", fallback=False) + self.gtk = KlippyGtk(self) self.init_style() self.set_icon_from_file(os.path.join(klipperscreendir, "styles", "icon.svg")) self.base_panel = BasePanel(self, title="Base Panel") - self.add(self.base_panel.layout) + self.add(self.base_panel.main_grid) self.show_all() - if show_cursor: + if self.show_cursor: self.get_window().set_cursor( Gdk.Cursor.new_for_display(Gdk.Display.get_default(), Gdk.CursorType.ARROW)) os.system("xsetroot -cursor_name arrow") @@ -317,32 +317,23 @@ class KlipperScreen(Gtk.Window): msg.get_child().set_line_wrap(True) msg.get_child().set_line_wrap_mode(Pango.WrapMode.WORD_CHAR) msg.connect("clicked", self.close_popup_message) - - close = Gtk.Button(label="X") - close.set_hexpand(False) - close.set_vexpand(True) - close.get_child().set_use_markup(True) - close.set_can_focus(False) - close.connect("clicked", self.close_popup_message) - - box = Gtk.Box() - box.set_size_request(self.width, -1) - box.set_halign(Gtk.Align.CENTER) - box.get_style_context().add_class("message_popup") + msg.get_style_context().add_class("message_popup") if level == 1: - box.get_style_context().add_class("message_popup_echo") + msg.get_style_context().add_class("message_popup_echo") elif level == 2: - box.get_style_context().add_class("message_popup_warning") + msg.get_style_context().add_class("message_popup_warning") else: - box.get_style_context().add_class("message_popup_error") + msg.get_style_context().add_class("message_popup_error") - box.add(msg) - box.add(close) + popup = Gtk.Popover.new(self.base_panel.titlebar) + popup.get_style_context().add_class("message_popup_popover") + popup.set_size_request(self.width, -1) + popup.set_halign(Gtk.Align.CENTER) + popup.add(msg) + popup.popup() - self.base_panel.layout.put(box, 0, 0) - - self.show_all() - self.popup_message = box + self.popup_message = popup + self.popup_message.show_all() if self._config.get_main_config().getboolean('autoclose_popups', True): GLib.timeout_add_seconds(10, self.close_popup_message) @@ -352,8 +343,7 @@ class KlipperScreen(Gtk.Window): def close_popup_message(self, widget=None): if self.popup_message is None: return - - self.base_panel.layout.remove(self.popup_message) + self.popup_message.popdown() self.popup_message = None def show_error_modal(self, err, e=""): @@ -448,7 +438,7 @@ class KlipperScreen(Gtk.Window): style_options['graph_colors']['sensor']['colors'][i] ) - css_data = css_data.replace("KS_FONT_SIZE", f"{self.gtk.get_font_size()}") + css_data = css_data.replace("KS_FONT_SIZE", f"{self.gtk.font_size}") style_provider = Gtk.CssProvider() style_provider.load_from_data(css_data.encode()) @@ -538,7 +528,8 @@ class KlipperScreen(Gtk.Window): box.pack_start(close, True, True, 0) box.set_halign(Gtk.Align.CENTER) box.get_style_context().add_class("screensaver") - self.base_panel.layout.put(box, 0, 0) + self.remove(self.base_panel.main_grid) + self.add(box) # Avoid leaving a cursor-handle close.grab_focus() @@ -551,8 +542,9 @@ class KlipperScreen(Gtk.Window): if self.screensaver is None: return False logging.debug("Closing Screensaver") - self.base_panel.layout.remove(self.screensaver) + self.remove(self.screensaver) self.screensaver = None + self.add(self.base_panel.main_grid) if self.use_dpms: self.wake_screen() else: @@ -914,7 +906,7 @@ class KlipperScreen(Gtk.Window): return box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) - box.set_size_request(self.gtk.get_content_width(), self.gtk.get_keyboard_height()) + box.set_size_request(self.gtk.content_width, self.gtk.keyboard_height) if self._config.get_main_config().getboolean("use-matchbox-keyboard", False): return self._show_matchbox_keyboard(box) @@ -970,6 +962,12 @@ class KlipperScreen(Gtk.Window): elif keyval_name == "BackSpace" and len(self._cur_panels) > 1 and self.keyboard is None: self.base_panel.back() + def update_size(self, *args): + self.width, self.height = self.get_size() + if self.vertical_mode != (self.width < self.height): + self.reload_panels() + self.vertical_mode = self.width < self.height + def main(): version = functions.get_software_version() diff --git a/styles/base.css b/styles/base.css index 76af6cd5..76dd3852 100644 --- a/styles/base.css +++ b/styles/base.css @@ -203,7 +203,12 @@ trough { } .action_bar { - /*border-right: 2px solid #444;*/ + /* min-width: 4.5em; */ + /* min-height: 4.5em; */ +} + +.title_bar { + min-height: 2em; } .content { @@ -293,6 +298,10 @@ trough { padding: 0 .5em; } +.heater-grid-temp { + min-width: 8em; +} + .keyboard_box { margin-top: 35px; } @@ -307,8 +316,17 @@ trough { border-radius: 0.7em; } +.message_popup_popover { + border: 0; + background-color: Transparent; + padding: 0; +} + .message_popup { - border-bottom: .1em solid white; + border: .1em solid white; + border-radius: 1em; + padding: 1em; + margin: 0; } .message_popup button{