Implementing new features
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
gi.require_version("Gdk", "3.0")
|
||||
|
||||
from gi.repository import Gdk, Gtk
|
||||
|
||||
|
||||
class ControlPanel(Gtk.Box):
|
||||
def __init__(self):
|
||||
super().__init__(orientation=Gtk.Orientation.VERTICAL, spacing=5)
|
||||
# Place the control panel in the top right
|
||||
self.set_halign(Gtk.Align.END)
|
||||
self.set_valign(Gtk.Align.START)
|
||||
|
||||
# Add the .control-panel CSS class to this widget
|
||||
context = self.get_style_context()
|
||||
context.add_class("control-panel")
|
||||
|
||||
def add_group(self, group):
|
||||
self.pack_start(group, False, False, 0)
|
||||
|
||||
|
||||
class ControlPanelGroup(Gtk.Expander):
|
||||
def __init__(self, title: str):
|
||||
Gtk.Expander.__init__(self, label=title)
|
||||
self._inner = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5)
|
||||
|
||||
# Set the size request to 200 pixels wide
|
||||
self.set_size_request(200, -1)
|
||||
|
||||
# Add a bit of margin after the header
|
||||
self._inner.set_margin_top(5)
|
||||
|
||||
self.add(self._inner)
|
||||
|
||||
def add_row(self, widget):
|
||||
self._inner.pack_start(widget, False, False, 0)
|
||||
|
||||
|
||||
class MyControlPanel(ControlPanel):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._first_panel = ControlPanelGroup("Some Buttons")
|
||||
self._first_panel.add_row(Gtk.Button(label="Button 1"))
|
||||
self._first_panel.add_row(Gtk.Button(label="Button 2"))
|
||||
self.add_group(self._first_panel)
|
||||
|
||||
self._second_panel = ControlPanelGroup("Extra Settings")
|
||||
self._second_panel.add_row(Gtk.Button(label="Button 3"))
|
||||
self._second_panel.add_row(Gtk.Button(label="Button 4"))
|
||||
self._second_panel.add_row(Gtk.CheckButton.new_with_label("First checkbox"))
|
||||
self._second_panel.add_row(Gtk.CheckButton.new_with_label("Second checkbox"))
|
||||
|
||||
combo = Gtk.ComboBoxText()
|
||||
combo.append("first", "First Choice")
|
||||
combo.append("second", "Second Choice")
|
||||
combo.append("third", "Third Choice")
|
||||
combo.append("forth", "This one is quite long")
|
||||
combo.set_active_id("first")
|
||||
self._second_panel.add_row(combo)
|
||||
|
||||
self.add_group(self._second_panel)
|
||||
|
||||
|
||||
class MapEditor(Gtk.DrawingArea):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.set_events(
|
||||
Gdk.EventMask.BUTTON_PRESS_MASK
|
||||
| Gdk.EventMask.BUTTON_RELEASE_MASK
|
||||
| Gdk.EventMask.POINTER_MOTION_MASK
|
||||
)
|
||||
|
||||
self._camera_x = 0 # The X coordinate of the camera
|
||||
self._camera_y = 0 # The Y coordinate of the camera
|
||||
self._mouse_x = 0 # The X coordinate of the pointer
|
||||
self._mouse_y = 0 # The Y coordinate of the pointer
|
||||
self._button = None # The currently held mouse button
|
||||
|
||||
# Connect to the draw and mouse events
|
||||
self.connect("draw", self.on_draw)
|
||||
self.connect("button-press-event", self.on_button_press_event)
|
||||
self.connect("button-release-event", self.on_button_release_event)
|
||||
self.connect("motion-notify-event", self.on_motion_notify_event)
|
||||
|
||||
def on_button_press_event(self, widget, event):
|
||||
self._mouse_x = event.x
|
||||
self._mouse_y = event.y
|
||||
self._button = event.button
|
||||
|
||||
def on_button_release_event(self, widget, event):
|
||||
self._mouse_x = 0
|
||||
self._mouse_y = 0
|
||||
self._button = None
|
||||
|
||||
def on_motion_notify_event(self, widget, event):
|
||||
if self._button == Gdk.BUTTON_SECONDARY:
|
||||
self._camera_x += event.x - self._mouse_x
|
||||
self._camera_y += event.y - self._mouse_y
|
||||
self._mouse_x = event.x
|
||||
self._mouse_y = event.y
|
||||
self.queue_draw()
|
||||
|
||||
def on_draw(self, widget, context):
|
||||
# Get the width and height of the widget
|
||||
width = self.get_allocated_width()
|
||||
height = self.get_allocated_height()
|
||||
|
||||
# Render a rectangle for the background of the editor
|
||||
context.set_source_rgb(0.11, 0.11, 0.11)
|
||||
context.rectangle(0, 0, width, height)
|
||||
context.fill()
|
||||
|
||||
# Render our grids
|
||||
context.set_line_width(1)
|
||||
for color, step in [(0.2, 10), (0.3, 100)]:
|
||||
context.set_source_rgb(color, color, color)
|
||||
y = int(self._camera_y % step) + 0.5
|
||||
while y < height:
|
||||
context.move_to(0, y)
|
||||
context.line_to(width, y)
|
||||
y += step
|
||||
x = int(self._camera_x % step) + 0.5
|
||||
while x < width:
|
||||
context.move_to(x, 0)
|
||||
context.line_to(x, height)
|
||||
x += step
|
||||
context.stroke()
|
||||
|
||||
|
||||
class MainWindow(Gtk.Window):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
self.set_title("Collapsible Controls Overlay Demo")
|
||||
|
||||
# Set the default window size to 800x800
|
||||
self.set_default_size(800, 800)
|
||||
# When our window is destroyed, exit the main event loop
|
||||
self.connect("destroy", Gtk.main_quit)
|
||||
|
||||
# Create our map editor and control panel instances
|
||||
self._editor = MapEditor()
|
||||
self._controls = MyControlPanel()
|
||||
|
||||
# Create the overlay widget
|
||||
self._overlay = Gtk.Overlay()
|
||||
|
||||
# Add our editor and control panel as overlays
|
||||
self._overlay.add_overlay(self._editor)
|
||||
self._overlay.add_overlay(self._controls)
|
||||
|
||||
# Add the overlay as the immediate child of the window
|
||||
self.add(self._overlay)
|
||||
|
||||
|
||||
def install_css():
|
||||
screen = Gdk.Screen.get_default()
|
||||
provider = Gtk.CssProvider()
|
||||
provider.load_from_data(
|
||||
b"""
|
||||
.control-panel {
|
||||
background-color: rgba(255,255,255,0.8);
|
||||
padding: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
"""
|
||||
)
|
||||
Gtk.StyleContext.add_provider_for_screen(screen, provider, 600)
|
||||
|
||||
|
||||
install_css()
|
||||
window = MainWindow()
|
||||
window.show_all()
|
||||
Gtk.main()
|
||||
|
||||
Reference in New Issue
Block a user