def make(self, global_settings, width, height): """Define Tile drawing properties""" if global_settings["names"] is True: self.obj.set_label(self.settings["name"]) icon_theme = Gtk.IconTheme.get_default() icon_info = icon_theme.lookup_icon(self.settings["icon"], 48, 0) image = GdkPixbuf.Pixbuf() try: image = image.new_from_file_at_scale(icon_info.get_filename(), global_settings["icon size"], global_settings["icon size"], False) except AttributeError: icon_theme = Gtk.IconTheme.get_default() icon_info = icon_theme.lookup_icon("unknown", 48, 0) image = GdkPixbuf.Pixbuf() image = image.new_from_file_at_scale(icon_info.get_filename(), global_settings["icon size"], global_settings["icon size"], False) image = Gtk.Image.new_from_pixbuf(image) self.obj.set_image(image) self.obj.set_image_position(Gtk.PositionType.TOP) self.obj.set_margin_top(common.scale(0.0073, height)) self.obj.set_margin_bottom(common.scale(0.0073, height)) self.obj.set_margin_left(common.scale(0.006, width)) self.obj.set_margin_right(common.scale(0.006, width))
def run(self): if self.getLocalCover(self.filelocation): img = GdkPixbuf.Pixbuf().new_from_file(self.folderjpg) elif self.getLastFMCover(self.artist, self.album): img = GdkPixbuf.Pixbuf().new_from_file(sopranoGlobals.CACHEFILE) else: img = sopranoGlobals.PLACEHOLDER return img
def pageAbout(self): oBox = Gtk.Box() oAboutDialog = Gtk.AboutDialog() oAboutDialog.set_license_type(Gtk.License.GPL_3_0) oAboutDialog.set_program_name(APPTITLE) oAboutDialog.set_copyright(APPAUTHOR + ' ' + ( APPYEAR if APPYEAR[-2:] == APPVERSION[:2] else APPYEAR + '-20' + APPVERSION[:2])) oAboutDialog.set_comments(_(APPDESCRIPTION)) oAboutDialog.set_authors(['Robert Tari <[email protected]>']) oAboutDialog.set_translator_credits(_('translator-credits')) oAboutDialog.set_version(APPVERSION) oAboutDialog.set_website(APPURL) oAboutDialog.set_website_label(APPURL) oAboutDialog.set_logo(GdkPixbuf.Pixbuf().new_from_file( getDataPath( '/usr/share/icons/hicolor/scalable/apps/ayatanawebmail.svg'))) oAboutDialog.get_content_area().reparent(oBox) oAboutDialog.get_content_area().set_hexpand(True) oAboutDialog.connect('activate_link', self.onActivateLinkAbout) lstChildren = oAboutDialog.action_area.get_children() for oWidget in lstChildren: if (isinstance(oWidget, Gtk.Button) and not isinstance(oWidget, Gtk.ToggleButton) ) or (isinstance(oWidget, Gtk.ToggleButton) and len(lstChildren) == 3 and oWidget == lstChildren[1]): oWidget.set_property('no-show-all', True) oWidget.set_property('visible', False) return oBox
def __init__(self, fileName): super().__init__() if fileName is not None: self.pixbuf = GdkPixbuf.Pixbuf().new_from_file(fileName) else: self.pixbuf = None
def __init__(self, app, settings): """Set default values for attributes.""" self.app = app general = settings["GENERAL"] # Generate window structure # Scrollable window for the image self.scrolled_win = Gtk.ScrolledWindow() self.scrolled_win.set_hexpand(True) self.scrolled_win.set_vexpand(True) # Viewport self.viewport = Gtk.Viewport() self.image = Gtk.Image() self.scrolled_win.add(self.viewport) self.viewport.add(self.image) self.scrolled_win.connect("key_press_event", self.app["eventhandler"].run, "IMAGE") # Settings self.animation_toggled = False self.fit_image = 1 # Checks if the image fits the window somehow self.trashdir = os.path.join(self.app.directory, "Trash") self.overzoom = general["overzoom"] self.rescale_svg = general["rescale_svg"] self.shuffle = general["shuffle"] self.zoom_percent = 1 self.imsize = [0, 0] self.is_anim = False self.pixbuf_original = GdkPixbuf.Pixbuf() self.pixbuf_iter = GdkPixbuf.PixbufAnimationIter() self.timer_id = 0
def fill_icon_view(liststore): pix=GdkPixbuf.Pixbuf() while len(__MATCHED_FILE__): temp_name=__MATCHED_FILE__.pop() liststore.append(\ [pix.new_from_file_at_scale(temp_name,200,200,1),\ str(temp_name)])
def menuitem_response(self, widget, string): if string == "gtk-media-play": if self.image.get_stock()[0] == "gtk-media-pause": self.player.set_state(gst.State.PAUSED) self.image.set_from_stock(gtk.STOCK_MEDIA_PLAY, 3) else: self.player.set_state(gst.State.PLAYING) self.image.set_from_stock(gtk.STOCK_MEDIA_PAUSE,3) elif string == "gtk-media-forward":self.durak(True) elif string == "gtk-media-rewind": self.durak(False) elif string == "gtk-media-next": self.sonraki(True) elif string == "gtk-media-previous": self.onceki(True) elif string == "Ses Dengesi":self.eko() elif string == "Ekran Görüntüsü Al": al = self.movie_window.get_allocation() width = al.width height = al.height screenshot = gdkpixbuf.Pixbuf.get_pixels( gdkpixbuf.Pixbuf( gdk.RGBA, True, 8, width, height), self.movie_window.get_window(), gdk.colormap_get_system(), 0, 0, 0, 0, width, height) screenshot.save("%s/%s.%s." %( home,self.window.get_title().replace("/",".") , self.time.replace("/","-") ) + "png", "png" ) del screenshot elif string == "gtk-about":abou.hakkinda()
def __init__(self, open_dialog_callback, get_several_hosts_function, get_single_host_function, icons): """Initializes the HostsSidebar. Initialization by itself does almost nothing, the application will inmediatly call create_model with the last workspace and create_view with that model upon startup. The model looks like this: | HOST_ID | HOST_OS_PIXBUF | OS_STR | DISPLAY_STR | VULN_COUNT| ====================================================================== | a923fd | PixBufIcon(linux)| linux | 192.168.1.2 (5) | 5 | """ Gtk.Widget.__init__(self) self.open_dialog_callback = open_dialog_callback self.get_hosts_function = get_several_hosts_function self.get_single_host_function = get_single_host_function self.model = Gtk.ListStore(str, GdkPixbuf.Pixbuf(), str, str, int) self.create_view() self.progress_label = Gtk.Label("") self.host_amount_total = 0 self.host_amount_in_model = 0 self.page = 1 self.host_id_to_iter = {} self.linux_icon = os.path.join(icons, "tux.png") self.windows_icon = os.path.join(icons, "windows.png") self.mac_icon = os.path.join(icons, "Apple.png") self.no_os_icon = os.path.join(icons, "TreeHost.png")
def SetFromStream(self, stream): if self.pixbuf is None: self.pixbuf = GdkPixbuf.Pixbuf() input_stream = Gio.MemoryInputStream.new_from_data(stream, None) self.pixbuf = self.pixbuf.new_from_stream(input_stream, None) return self
def _cv_image_to_pixbuf(self, image): """ Convert cv image (numpy array) to a gtk pixelbuffer """ image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) return GdkPixbuf.Pixbuf().new_from_data(image.tostring(), 0, False, 8, image.shape[1], image.shape[0], image.shape[1] * 3)
def __init__(self, parent): Gtk.AboutDialog.__init__(self, title=_("About"), parent=parent, modal=True) self.set_version(VERSION) new_image = GdkPixbuf.Pixbuf().new_from_file(LOGO_IMAGE_PATH) self.set_logo(new_image)
def gray_scale_pixBuf(pb, copy): pb2 = GdkPixbuf.Pixbuf( GdkPixbuf.Colorspace.RGB, False, 8, pb.get_width(), pb.get_height()) pb.saturate_and_pixelate(pb2, 0, 0) return pb2
def __drag_begin_cb(self, widget, context): # Drag and Drop pixbuf = GdkPixbuf.Pixbuf(GdkPixbuf.Colorspace.RGB, True, 8, style.SMALL_ICON_SIZE, style.SMALL_ICON_SIZE) red = self._color.red / 257 green = self._color.green / 257 blue = self._color.blue / 257 pixbuf.fill(red << 24 + green << 16 + blue << 8 + 0xff) context.set_icon_pixbuf(pixbuf)
def tile(self, pathtofile, char): if pathtofile == char: thisTile = Gtk.Label(char) else: thisTile = Gtk.Image() if pathtofile == '': thisTile.set_size_request(32, 32) else: pixbuf = GdkPixbuf.Pixbuf().new_from_file_at_scale( pathtofile, 32, 32, True) thisTile.set_from_pixbuf(pixbuf) return thisTile
def about_dialog(_): """Set-up About Dialog""" widget = Gtk.AboutDialog() widget.set_license_type(Gtk.License.MIT_X11) widget.set_authors(["Binyamin Green https://binyam.in"]) widget.set_version("1.0.0") widget.set_website("https://github.com/b3u/pyconvert/") widget.set_website_label("Source Code") widget.set_logo(GdkPixbuf.Pixbuf().new_from_file_at_size( 'logo.svg', 48, 48)) widget.connect("response", lambda w, _: w.close()) widget.run()
def screenshot(file='screenshot.png', timeStamp=True): """ This function wraps the ImageMagick import command to take a screenshot. The file argument may be specified as 'foo', 'foo.png', or using any other extension that ImageMagick supports. PNG is the default. By default, screenshot filenames are in the format of foo_YYYYMMDD-hhmmss.png . The timeStamp argument may be set to False to name the file foo.png. """ if not isinstance(timeStamp, bool): raise TypeError("timeStampt must be True or False") # config is supposed to create this for us. If it's not there, bail. assert os.path.isdir(config.scratchDir) baseName = ''.join(file.split('.')[0:-1]) fileExt = file.split('.')[-1].lower() if not baseName: baseName = file fileExt = 'png' if timeStamp: ts = TimeStamp() newFile = ts.fileStamp(baseName) + '.' + fileExt path = config.scratchDir + newFile else: newFile = baseName + '.' + fileExt path = config.scratchDir + newFile from gi.repository import Gdk from gi.repository import GObject from gi.repository import GdkPixbuf rootWindow = Gdk.get_default_root_window() geometry = rootWindow.get_geometry() pixbuf = GdkPixbuf.Pixbuf(colorspace=GdkPixbuf.Colorspace.RGB, has_alpha=False, bits_per_sample=8, width=geometry[2], height=geometry[3]) pixbuf = Gdk.pixbuf_get_from_window(rootWindow, 0, 0, geometry[2], geometry[3]) # GdkPixbuf.Pixbuf.save() needs 'jpeg' and not 'jpg' if fileExt == 'jpg': fileExt = 'jpeg' try: pixbuf.savev(path, fileExt, [], []) except GObject.GError: raise ValueError("Failed to save screenshot in %s format" % fileExt) assert os.path.exists(path) logger.log("Screenshot taken: " + path) return path
def __init__(self): Gtk.Window.__init__(self) GLib.set_application_name('PyConvert') i = Gtk.IconSize.SMALL_TOOLBAR icon_size = Gtk.IconSize(i).lookup(i) self.icon = GdkPixbuf.Pixbuf().new_from_file_at_size( "logo.svg", icon_size[1], icon_size[2]) self.set_default_icon(self.icon) self.set_title("PyConvert") self.set_border_width(10) try: # Cache rates self.rates: dict = json.load(open("rates.json")) except FileNotFoundError: # Create file if not found req = requests.get( "https://api.exchangeratesapi.io/latest?base=USD") rates = req.json().get("rates") json.dump(rates, open("rates.json", mode="x")) self.rates: dict = rates self.header_bar() # self.set_interactive_debugging(True) self.grid = Gtk.Grid() self.grid.set_row_spacing(6) self.grid.set_column_spacing(6) self.entry = Gtk.SpinButton().new_with_range(0, 9999, 0.10) self.entry.set_digits(2) self.grid.attach(self.entry, 0, 0, 1, 1) self.grid.attach(Gtk.Label(label="USD as "), 1, 0, 1, 1) self.dropdown = Gtk.ComboBoxText() for key in self.rates: self.dropdown.append(key, key) self.grid.attach(self.dropdown, 2, 0, 2, 1) btn_convert = Gtk.Button().new_with_label(label="Convert") btn_convert.connect("clicked", self.convert) self.grid.attach(btn_convert, 0, 1, 2, 1) self.output = Gtk.Entry(placeholder_text="0.00", editable=False) self.grid.attach(self.output, 2, 1, 1, 1) self.add(self.grid)
def __init__(self, width, height): super().__init__() pygame.init() self.last_tick_time = time.perf_counter() self.surface = pygame.Surface((width, height)) self.fps = 0 self.pixbuf = GdkPixbuf.Pixbuf() GObject.timeout_add(16, self.on_draw)
def getBox(self,iso): label = gtk.Label(iso.name) pixbuf = GdkPixbuf.Pixbuf().new_from_file("iso/"+iso.image) pixbuf.scale_simple(imageWidth,imageHeight,GdkPixbuf.InterpType.BILINEAR) image = gtk.Image().new_from_pixbuf(pixbuf) box = gtk.Box() box.set_border_width(10) box.set_orientation(gtk.Orientation.VERTICAL) box.pack_start(image,True,True,2) box.pack_end(label,True,True,2) return box
def create_model(self, hosts): """Creates a model for a lists of hosts. The model contians the host_id in the first column, the icon as a GdkPixbuf.Pixbuf() in the second column and a display_str with the host_name and the vulnerability count on the third column, like this: | HOST_ID | HOST_OS_PIXBUF | OS_STR | DISPLAY_STR | VULN_COUNT| ====================================================================== | a923fd | PixBufIcon(linux)| linux | 192.168.1.2 (5) | 5 | """ hosts_model = Gtk.ListStore(str, GdkPixbuf.Pixbuf(), str, str, int) self.current_model = hosts_model for host in hosts: self.__add_host_to_model(host) return self.current_model
def drawHistogram(self,area,context): global __HISTOGRAM__ if __HISTOGRAM__ is not None: pix=GdkPixbuf.Pixbuf() img=pix.new_from_data(__HISTOGRAM__.tostring(),\ GdkPixbuf.Colorspace.RGB,\ False,8,\ __HISTOGRAM__.shape[1],\ __HISTOGRAM__.shape[0],\ __HISTOGRAM__.shape[1]*3,\ None,None) gdk.cairo_set_source_pixbuf(context,img,0,0) context.fill() context.paint() __HISTOGRAM__=None
def on_realize(self, entry): layout = self.get_layout().copy() layout.set_markup("<span foreground='dark gray'>%s</span>" % self.default_text) extents = layout.get_pixel_extents()[1] drawable = Gdk.Pixmap(self.get_parent_window(), extents[2], extents[3]) gc = Gdk.GC(drawable) gc2 = entry.props.style.base_gc[0] drawable.draw_rectangle(gc2, True, *extents) drawable.draw_layout(gc, 0, 0, layout) pixbuf = GdkPixbuf.Pixbuf(Gdk.COLORSPACE_RGB, True, 8, extents[2], extents[3]) pixbuf.get_from_drawable(drawable, drawable.get_colormap(), 0, 0, *extents) self.empty_pixbuf = pixbuf if not Gtk.Entry.get_text(self): self.props.primary_icon_pixbuf = pixbuf
def create_flowbox(self, text, default): if not default: paths = fn.get_saved_path() if len(paths) < 1: if len(text) < 1: paths = "/usr/share/archlinux-betterlockscreen/wallpapers/" if not fn.os.path.isdir(paths): paths = "/usr/share/archlinux-betterlockscreen/wallpapers/" if not fn.os.path.isdir(paths): return 0 else: paths = text else: paths = "/usr/share/archlinux-betterlockscreen/wallpapers/" if not fn.os.path.isdir(paths): paths = "/usr/share/archlinux-betterlockscreen/wallpapers/" if not fn.os.path.isdir(paths): return 0 if paths.endswith("/"): paths = paths[:-1] if not fn.os.path.isdir(paths): GLib.idle_add(self.status.set_text, "That directory not found!") return 0 try: ext = [".png", ".jpg", ".jpeg"] images = [ x for x in fn.os.listdir(paths) for j in ext if j in x.lower() if self.search.get_text() in x ] # noqa GLib.idle_add(self.status.set_text, "Loading images...") for image in images: # fbchild = Gtk.FlowBoxChild() pb = GdkPixbuf.Pixbuf().new_from_file_at_size( paths + "/" + image, 328, 328) # noqa pimage = Gtk.Image() pimage.set_name(paths + "/" + image) pimage.set_from_pixbuf(pb) # print(image) # fbchild.add(pimage) GLib.idle_add(self.fb.add, pimage) pimage.show_all() except Exception as e: print(e) GLib.idle_add(self.status.set_text, "")
def __init__(self): Gtk.Window.__init__(self, Gtk.WindowType.POPUP, title='') self.set_decorated(False) self.set_resizable(False) self.set_size_request(500, 250) self.set_position(Gtk.WindowPosition.CENTER) main_vbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=1) self.add(main_vbox) self.image = Gtk.Image() pimage = GdkPixbuf.Pixbuf().new_from_file_at_size( base_dir + "/images/splash.png", 500, 250) self.image.set_from_pixbuf(pimage) main_vbox.pack_start(self.image, True, True, 0) self.show_all()
def update_cover(self, widget, source, entry): print('update_cover') self.oldval = 0 # force a redraw if entry: print('entry') album = source.album_manager.model.get_from_dbentry(entry) self.pixbuf = GdkPixbuf.Pixbuf().new_from_file(album.cover.original) self.window_resize(None) self.frame.set_shadow_type(Gtk.ShadowType.NONE) else: print('no pixbuf') self.pixbuf = None self.frame.set_shadow_type(Gtk.ShadowType.ETCHED_OUT) if self.stack.get_visible_child_name() == "image1": self.image1.queue_draw() else: self.image2.queue_draw()
def create_model(self, hosts): """Creates a model for a lists of hosts. The model contians the host_id in the first column, the icon as a GdkPixbuf.Pixbuf() in the second column and a display_str with the host_name and the vulnerability count on the third column, like this: | HOST_ID | HOST_OS_PIXBUF | DISPLAY_STR | ================================================= | a923fd | LINUX_ICON | 192.168.1.2 (5) | """ def compute_vuln_count(host): """Returns the total vulnerability count for a given host""" vuln_count = 0 vuln_count += len(host.getVulns()) for interface in host.getAllInterfaces(): vuln_count += len(interface.getVulns()) for service in interface.getAllServices(): vuln_count += len(service.getVulns()) return str(vuln_count) def decide_icon(os): """Decides the correct Pixbuf icon for a OS. None if OS not found or not recognized. """ os = os.lower() if "linux" in os or "unix" in os: icon = GdkPixbuf.Pixbuf.new_from_file(self.linux_icon) elif "windows" in os: icon = GdkPixbuf.Pixbuf.new_from_file(self.windows_icon) elif "mac" in os: icon = GdkPixbuf.Pixbuf.new_from_file(self.mac_icon) else: icon = None return icon hosts_model = Gtk.ListStore(str, GdkPixbuf.Pixbuf(), str) for host in hosts: vuln_count = compute_vuln_count(host) display_str = host.name + " (" + vuln_count + ")" os = host.getOS() hosts_model.append([host.id, decide_icon(os), display_str]) self.current_model = hosts_model return hosts_model
def onExpose(self,area,context): global __IMAGE_PATH__ global __HISTOGRAM__ if __IMAGE_PATH__ is not None: pix=GdkPixbuf.Pixbuf() #print __IMAGE_PATH__ img=pix.new_from_file_at_scale(__IMAGE_PATH__,300,300,1) gdk.cairo_set_source_pixbuf(context,img,0,0) context.fill() context.paint() if __HISTOGRAM__ is None and __IMAGE_PATH__ is not None : adjust_image=Adjust() adjust_image.image=cv2.imread(__IMAGE_PATH__) self.hist_calc=Histogram(adjust_image.image) self.hist_calc.get_histogram() __HISTOGRAM__=self.hist_calc.draw_histogram() #print __HISTOGRAM__ self.histogram.queue_draw()
def __init__(self, app): """Set default values for attributes.""" super(Image, self).__init__() self._app = app # Settings and defaults self.fit_image = "overzoom" self._pixbuf_iter = GdkPixbuf.PixbufAnimationIter() self._pixbuf_original = GdkPixbuf.Pixbuf() self.zoom_percent = 1 self._identifier = 0 self._size = (1, 1) self._timer_id = 0 self._faulty_image = False # Connect signals self._app["transform"].connect("changed", self._on_image_changed) self._app["commandline"].search.connect("search-completed", self._on_search_completed) settings.connect("changed", self._on_settings_changed)
def onAboutClicked(self, pWidget, pData=None): pAboutdialog = Gtk.AboutDialog() pAboutdialog.set_transient_for(g_pWindow) pAboutdialog.set_title( _('About {application}').format(application=APPTITLE)) pAboutdialog.set_license_type(Gtk.License.GPL_3_0) pAboutdialog.set_program_name(APPTITLE) pAboutdialog.set_copyright(APPAUTHOR + ' ' + ( APPYEAR if APPYEAR[-2:] == APPVERSION[:2] else APPYEAR + '-20' + APPVERSION[:2])) pAboutdialog.set_comments(_(APPDESCRIPTION)) pAboutdialog.set_authors([APPAUTHOR + ' <' + APPMAIL + '>']) pAboutdialog.set_translator_credits(_('translator-credits')) pAboutdialog.set_version(APPVERSION) pAboutdialog.set_website(APPURL) pAboutdialog.set_website_label(APPURL) pAboutdialog.set_logo(GdkPixbuf.Pixbuf().new_from_file( getDataPath('/usr/share/icons/hicolor/scalable/apps/' + APPNAME + '.svg'))) pAboutdialog.run() pAboutdialog.destroy()
class Pointer(object): """ Manage and draw the software “laser pointer” to point at the slide. Displays a pointer of chosen color on the current slide (in both windows), either on all the time or only when clicking while ctrl pressed. Args: config (:class:`~pympress.config.Config`): A config object containing preferences builder (:class:`~pympress.builder.Builder`): A builder from which to load widgets """ #: :class:`~GdkPixbuf.Pixbuf` to read XML descriptions of GUIs and load them. pointer = GdkPixbuf.Pixbuf() #: `(float, float)` of position relative to slide, where the pointer should appear pointer_pos = (.5, .5) #: `bool` indicating whether we should show the pointer show_pointer = False #: :class:`~pympress.pointer.PointerMode` indicating the pointer mode pointer_mode = PointerMode.MANUAL #: The :class:`~pympress.pointer.PointerMode` to which we toggle back old_pointer_mode = PointerMode.CONTINUOUS #: A reference to the UI's :class:`~pympress.config.Config`, to update the pointer preference config = None #: :class:`~Gtk.DrawingArea` Slide in the Presenter window, used to reliably set cursors. p_da_cur = None #: :class:`~Gtk.DrawingArea` Slide in the Contents window, used to reliably set cursors. c_da = None #: :class:`~Gtk.AspectFrame` Frame of the Contents window, used to reliably set cursors. c_frame = None #: a `dict` of the :class:`~Gtk.RadioMenuItem` selecting the pointer mode pointermode_radios = {} #: callback, to be connected to :func:`~pympress.ui.UI.redraw_current_slide` redraw_current_slide = lambda: None def __init__(self, config, builder): super(Pointer, self).__init__() self.config = config builder.load_widgets(self) self.redraw_current_slide = builder.get_callback_handler('redraw_current_slide') default_mode = config.get('presenter', 'pointer_mode') default_color = 'pointer_' + config.get('presenter', 'pointer') try: default_mode = PointerMode[default_mode.upper()] except KeyError: default_mode = PointerMode.MANUAL self.activate_pointermode(default_mode) for radio_name in ['continuous', 'manual', 'disabled']: radio = builder.get_object('pointermode_' + radio_name) radio.set_name('pointermode_' + radio_name) radio.set_active(radio_name == default_mode.name.lower()) self.pointermode_radios[radio_name] = radio self.load_pointer(default_color) for radio_name in ['pointer_red', 'pointer_blue', 'pointer_green']: radio = builder.get_object(radio_name) radio.set_name(radio_name) radio.set_active(radio_name == default_color) def load_pointer(self, name): """ Perform the change of pointer using its color name. Args: name (`str`): Name of the pointer to load """ if name in ['pointer_red', 'pointer_green', 'pointer_blue']: self.pointer = GdkPixbuf.Pixbuf.new_from_file(util.get_icon_path(name + '.png')) else: raise ValueError('Wrong color name') def change_pointercolor(self, widget): """ Callback for a radio item selection as pointer color. Args: widget (:class:`~Gtk.RadioMenuItem`): the selected radio item in the pointer type selection menu """ if widget.get_active(): assert widget.get_name().startswith('pointer_') self.load_pointer(widget.get_name()) self.config.set('presenter', 'pointer', widget.get_name()[len('pointer_'):]) def activate_pointermode(self, mode = None): """ Activate the pointer as given by mode. Depending on the given mode, shows or hides the laser pointer and the normal mouse pointer. Args: mode (:class:`~pympress.pointer.PointerMode`): The mode to activate """ # Set internal variables, unless called without mode (from ui, after windows have been mapped) if mode == self.pointer_mode: return elif mode is not None: self.old_pointer_mode, self.pointer_mode = self.pointer_mode, mode self.config.set('presenter', 'pointer_mode', self.pointer_mode.name.lower()) # Set mouse pointer and cursors on/off, if windows are already mapped self.show_pointer = False for slide_widget in [self.p_da_cur, self.c_da]: ww, wh = slide_widget.get_allocated_width(), slide_widget.get_allocated_height() if max(ww, wh) == 1: continue pointer_coordinates = slide_widget.get_window().get_pointer() if 0 < pointer_coordinates.x < ww and 0 < pointer_coordinates.y < wh \ and self.pointer_mode == PointerMode.CONTINUOUS: # Laser activated right away self.pointer_pos = (pointer_coordinates.x / ww, pointer_coordinates.y / wh) self.show_pointer = True extras.Cursor.set_cursor(slide_widget, 'invisible') else: extras.Cursor.set_cursor(slide_widget, 'parent') self.redraw_current_slide() def change_pointermode(self, widget): """ Callback for a radio item selection as pointer mode (continuous, manual, none). Args: widget (:class:`~Gtk.RadioMenuItem`): the selected radio item in the pointer type selection menu """ if widget.get_active(): mode = PointerMode[widget.get_name()[len('pointermode_'):].upper()] self.activate_pointermode(mode) def toggle_pointermode(self): """ Callback for shortcut to switch on/off continuous pointer. """ mode = self.old_pointer_mode if self.pointer_mode == PointerMode.CONTINUOUS else PointerMode.CONTINUOUS self.activate_pointermode(mode) self.pointermode_radios[mode.name.lower()].set_active(True) def render_pointer(self, cairo_context, ww, wh): """ Draw the laser pointer on screen. Args: cairo_context (:class:`~cairo.Context`): The canvas on which to render the pointer ww (`int`): The widget width wh (`int`): The widget height """ if self.show_pointer: x = ww * self.pointer_pos[0] - self.pointer.get_width() / 2 y = wh * self.pointer_pos[1] - self.pointer.get_height() / 2 Gdk.cairo_set_source_pixbuf(cairo_context, self.pointer, x, y) cairo_context.paint() def track_pointer(self, widget, event): """ Move the laser pointer at the mouse location. Args: widget (:class:`~Gtk.Widget`): the widget which has received the event. event (:class:`~Gdk.Event`): the GTK event. Returns: `bool`: whether the event was consumed """ if self.show_pointer: ww, wh = widget.get_allocated_width(), widget.get_allocated_height() ex, ey = event.get_coords() self.pointer_pos = (ex / ww, ey / wh) self.redraw_current_slide() return True else: return False def track_enter_leave(self, widget, event): """ Switches laser off/on in continuous mode on leave/enter slides. In continuous mode, the laser pointer is switched off when the mouse leaves the slide (otherwise the laser pointer "sticks" to the edge of the slide). It is switched on again when the mouse reenters the slide. Args: widget (:class:`~Gtk.Widget`): the widget which has received the event. event (:class:`~Gdk.Event`): the GTK event. Returns: `bool`: whether the event was consumed """ # Only handle enter/leave events on one of the current slides if self.pointer_mode != PointerMode.CONTINUOUS or widget not in [self.c_da, self.p_da_cur]: return False if event.type == Gdk.EventType.ENTER_NOTIFY: self.show_pointer = True extras.Cursor.set_cursor(widget, 'invisible') elif event.type == Gdk.EventType.LEAVE_NOTIFY: self.show_pointer = False extras.Cursor.set_cursor(widget, 'parent') self.redraw_current_slide() return True def toggle_pointer(self, widget, event): """ Track events defining when the laser is pointing. Args: widget (:class:`~Gtk.Widget`): the widget which has received the event. event (:class:`~Gdk.Event`): the GTK event. Returns: `bool`: whether the event was consumed """ if self.pointer_mode in {PointerMode.DISABLED, PointerMode.CONTINUOUS}: return False ctrl_pressed = event.get_state() & Gdk.ModifierType.CONTROL_MASK if ctrl_pressed and event.type == Gdk.EventType.BUTTON_PRESS: self.show_pointer = True extras.Cursor.set_cursor(widget, 'invisible') # Immediately place & draw the pointer return self.track_pointer(widget, event) elif self.show_pointer and event.type == Gdk.EventType.BUTTON_RELEASE: self.show_pointer = False extras.Cursor.set_cursor(widget, 'parent') self.redraw_current_slide() return True else: return False