Part of Slepp's ProjectsPastebinTURLImagebinFilebin
Feedback -- English French German Japanese
Create Upload Newest Tools Donate
Sign In | Create Account

Paste Description for Marc Quinton

DesktopGadget

Marc Quinton
Thursday, June 28th, 2007 at 10:30:11am MDT 

  1. <?php
  2.  
  3. /**
  4. * Author: Marc Quinton
  5. * Licence : LGPL
  6. *
  7. *  DesktopGadget : a small window displaying some information (a clock here) ;
  8. *       - you can move this window around the screen with mouse,
  9. *   - window can be closed, iconified (need GtkStatusIcon to remap, but not implemented)
  10. *       - window position is stored in INI file (based on script filename)
  11. *  this is a "popup window" ; could be a Toplevel window with no decoration and with some attributes set.
  12. *
  13. *
  14. *
  15. * see : http://gtk.php.net/manual/en/gdk.enum.windowtypehint.php
  16. */
  17.  
  18. # allways display errors during developpement.
  19.  
  20. define ('DIR', dirname(__FILE__));
  21. define ('INI', basename(__FILE__, '.php') . '.ini' );
  22.  
  23. class Config {
  24.  
  25.         protected $data;
  26.         protected $changed;
  27.         protected $auto_save;
  28.         protected $file;
  29.         protected $defaults;
  30.  
  31.         public function __construct($defaults=null, $file=INI){
  32.                 $this->data = array();
  33.  
  34.                 if($file == null)
  35.                         $this->file = $this->get_default_file();
  36.                 else
  37.                         $this->file = $file;
  38.  
  39.                 $this->set_defaults($defaults);
  40.                 $this->load();
  41.                 $this->changed = false;
  42.                 $this->auto_save = true;
  43.         }
  44.  
  45.         public function __destruct(){
  46.                 if($this->changed){
  47.                         $this->save();
  48.                 }
  49.         }
  50.  
  51.         public function __get($name){
  52.                 return $this->data[$name];
  53.         }
  54.  
  55.         public function __set($name, $value){
  56.                 # echo "Config::set($name=$value)\n";
  57.                 if(isset($this->data[$name])){
  58.                         if($this->data[$name] != $value){
  59.                                 $this->data[$name] = $value;
  60.                                 $this->changed = true;
  61.                         }
  62.                 } else{
  63.                         $this->data[$name] = $value;
  64.                         $this->changed = true;
  65.                 }
  66.         }
  67.  
  68.         public function __isset($name){
  69.                 return isset($this->data[$name]);
  70.         }
  71.  
  72.         public function __unset($name){
  73.                 unset($this->data[$name]);
  74.         }
  75.  
  76.         public function keys(){
  77.                 return array_keys($this->data);
  78.         }
  79.  
  80.         public function save(){
  81.                 $bool = file_put_contents($this->file(), serialize($this->data));
  82.                 if($bool === false)
  83.                         throw new Exception('error writing file ' . $this->file());
  84.                 $this->changed = false;
  85.                 return $bool;
  86.         }
  87.  
  88.         public function load(){
  89.                 if(file_exists($this->file())){
  90.                         $this->data = unserialize(file_get_contents($this->file()));
  91.                         return true;
  92.                 }
  93.                 return false;
  94.         }
  95.  
  96.         protected function get_default_file(){
  97.                 return basename(__FILE__, '.php') . '.ini' ;
  98.         }
  99.  
  100.         protected function set_defaults($defaults){
  101.                 $this->data = $defaults;
  102.         }
  103.  
  104.         protected function file(){
  105.                 return $this->file;
  106.         }
  107. }
  108.  
  109. class Frame extends GtkEventBox{
  110.  
  111.         protected $container;
  112.  
  113.         public function __construct($border_color='#aaa', $background='#EEE', $border_width=1){
  114.                 parent::__construct();
  115.                 $this->set_border_width(0);
  116.                 $this->modify_bg(Gtk::STATE_NORMAL, GdkColor::parse($border_color));
  117.                 $this->container = new GtkEventBox();
  118.                 parent::add($this->container);
  119.                 $this->container->modify_bg(Gtk::STATE_NORMAL, GdkColor::parse($background));
  120.                 $this->container->set_border_width($border_width);
  121.         }
  122.  
  123.         public function add($w){
  124.                 $this->container->add($w);
  125.         }
  126. }
  127.  
  128. class Button extends GtkEventBox{
  129.         protected $label;
  130.         protected $callbacks;
  131.        
  132.         public function __construct($label){
  133.                 parent::__construct();
  134.  
  135.                 $this->modify_bg(Gtk::STATE_NORMAL, GdkColor::parse('#EEE'));
  136.                         $frame = new Frame();
  137.                         $this->add($frame);
  138.                                 $frame->add($this->label = new GtkLabel($label));
  139.                                 $this->label->modify_font(new PangoFontDescription('Sans Bold 6'));
  140.        
  141.                 $this->add_events(Gdk::BUTTON_PRESS_MASK);
  142.                 $this->connect('button-press-event'array($this, 'button_press_event'));
  143.                 # $this->connect('motion-notify-event', array($this, 'motion_notify_event'));
  144.                 $this->callbacks = array();
  145.  
  146.                 $this->set_border_width(0);
  147.        
  148.         }
  149.  
  150.         public function connect($signal, $callback){
  151.                 if($signal == 'clicked'){
  152.                         $this->callbacks[] = $callback;
  153.                 }
  154.                 else
  155.                         parent::connect($signal, $callback);
  156.         }
  157.  
  158.         public function motion_notify_event($w, $event){
  159.                 return true;
  160.         }
  161.  
  162.         public function button_press_event($selft, $event){
  163.                 foreach($this->callbacks as $callback){
  164.                         call_user_func($callback, $event);
  165.                 }
  166.                 return true;
  167.         }
  168. }
  169.  
  170.  
  171. class MovableWidget extends GtkEventBox{
  172.  
  173.         protected $clic_point;
  174.         protected $config;
  175.  
  176.         public function __construct($config=null){
  177.                 parent::__construct();
  178.  
  179.                 $this->add_events(Gdk::POINTER_MOTION_MASK|Gdk::BUTTON_PRESS_MASK);
  180.                 $this->connect('motion-notify-event', array($this, 'motion_notify_event'));
  181.                 $this->connect('button-press-event'array($this, 'button_press_event'));
  182.                 $this->connect_simple('realize', array($this, 'on_realize'));
  183.                 $this->click_point = null;
  184.  
  185.                 if($config == null)
  186.                         $this->config = new Config();
  187.                 else
  188.                         $this->config = $config;
  189.  
  190.                 $this->set_border_width(0);
  191.         }
  192.  
  193.         public function on_realize(){
  194.                 if(isset($this->config->x)){
  195.                         $this->get_window()->move($this->config->x, $this->config->y);
  196.                 }
  197.         }
  198.  
  199.         public function button_press_event($w, $event){
  200.                 $this->click_point = array(
  201.                         'x_root' => $event->x_root,
  202.                         'y_root' => $event->y_root
  203.                 );
  204.         }
  205.  
  206.  
  207.         # move window location following mouse.
  208.         public function motion_notify_event($w, $event){
  209.  
  210.                 $state = $event->state & ~(Gdk::BUTTON_MOTION_MASK);
  211.  
  212.                 # no button press
  213.                 if($state == 0)
  214.                         return;
  215.  
  216.                 $win = $this->get_window();
  217.                 $pos = $win->get_position();
  218.  
  219.                 $x = $pos[0] + $event->x_root - $this->click_point['x_root'];
  220.                 $y = $pos[1] + $event->y_root - $this->click_point['y_root'];
  221.  
  222.  
  223.                 $win->move($x, $y);
  224.                 $this->config->x = $x;
  225.                 $this->config->y = $y;
  226.  
  227.                 $this->click_point = array(
  228.                         'x_root' => $event->x_root,
  229.                         'y_root' => $event->y_root
  230.                 );
  231.         }
  232.  
  233.         public function get_window(){
  234.                 $parent = $this;
  235.                 do{
  236.                         $w = $parent;
  237.                         $parent = $w->get_parent();
  238.                 } while($parent != null);
  239.  
  240.                 return $w;
  241.         }
  242. }
  243.  
  244. class ClockWidget extends GtkLabel{
  245.         protected $timeout_id;
  246.         protected $format;
  247.  
  248.         public function __construct($format = 'd/m - H:i:s'){
  249.                 parent::__construct();
  250.                 $this->format=$format;
  251.                 $this->timeout_id = Gtk::timeout_add(1000, array($this, 'on_timeout'));
  252.                 $this->modify_font(new PangoFontDescription('Sans 7'));
  253.                 $this->on_timeout();
  254.         }
  255.  
  256.         public function on_timeout(){
  257.                 $this->set_text(date($this->format));
  258.                 return true;
  259.         }
  260. }
  261.  
  262. class TitleBar extends MovableWidget{
  263.  
  264.         protected $hbox;
  265.  
  266.         public function __construct($config, $title){
  267.                 parent::__construct($config);
  268.                 $this->hbox = new GtkHbox();
  269.  
  270.                 $this->hbox->pack_start($this->label = new GtkLabel($title));
  271.                 $this->label->modify_font(new PangoFontDescription('Sans Bold 7'));
  272.  
  273.                 $this->hbox->pack_end($this->button_close = new Button(' x '), false, false);
  274.                 $this->hbox->pack_end($this->button_minimize = new Button(' ^ '), false, false);
  275.                 $this->hbox->pack_end($this->button_reduce = new Button(' - '), false, false);
  276.  
  277.                 $this->button_close->connect('clicked', array($this, 'on_button_close'));
  278.                 $this->button_minimize->connect('clicked', array($this, 'on_button_minimize'));
  279.                 $this->button_reduce->connect('clicked', array($this, 'on_button_reduce'));
  280.  
  281.                 $this->modify_bg(Gtk::STATE_NORMAL, GdkColor::parse('#aaa'));
  282.                 $this->add($this->hbox);
  283.                 $this->show_all();
  284.         }
  285.  
  286.         public function on_button_close(){
  287.                 Gtk::main_quit();
  288.         }
  289.         public function on_button_minimize(){
  290.                 $this->get_window()->hide_all();
  291.         }
  292.  
  293.         public function on_button_reduce(){
  294.                 static $visible = true;
  295.                 $w = $this->allocation->width;
  296.                 if($visible){
  297.                         $this->managed_widget->hide_all();
  298.                         $h = $this->allocation->height;
  299.                 }
  300.                 else{
  301.                         $this->managed_widget->show_all();
  302.                         $h = $this->allocation->height +$this->managed_widget->allocation->height;
  303.                 }
  304.                 $visible = !$visible;
  305.                 $this->get_window()->resize($w, $h);
  306.         }
  307.  
  308.         public function manage($widget){
  309.                 $this->managed_widget = $widget;
  310.         }
  311. }
  312.  
  313. class DesktopGadget{
  314.  
  315.         protected $config;
  316.  
  317.         protected $pannel;
  318.         protected $title_bar;
  319.         protected $window;
  320.  
  321.         function __construct($title, $type=1){
  322.  
  323.                 $this->config = new Config();
  324.  
  325.                 switch($type){
  326.  
  327.                 case 1:
  328.                         $this->window = new GtkWindow(Gtk::WINDOW_POPUP)# display over any window
  329.                         break;
  330.  
  331.                 case 2:
  332.                         $this->window = new GtkWindow();
  333.                         $this->window->set_type_hint(Gdk::WINDOW_TYPE_HINT_DOCK)# display over any window, below gtk panel
  334.                         break;
  335.  
  336.                 case 3:
  337.                         $this->window = new GtkWindow();
  338.                         $this->window->set_type_hint(Gdk::WINDOW_TYPE_HINT_DESKTOP)# display on gtk desktop, under any window
  339.                         break;
  340.  
  341.                 case 4:
  342.                         # raw toplevel + some attributes  ; won't move over panel or outside screen
  343.                         $this->window = new GtkWindow();
  344.                         $this->window->set_skip_taskbar_hint(true);
  345.                         $this->window->set_skip_pager_hint(true);
  346.                         $this->window->set_keep_above(true);
  347.                         # $this->window->set_keep_below(true);
  348.                         $this->window->stick();
  349.                         $this->window->set_decorated(false);
  350.                         break;
  351.        
  352.                 case 'parameters-to-try':
  353.                         # http://gtk.php.net/manual/en/gdk.enum.windowtypehint.php
  354.                         $this->window->set_skip_taskbar_hint(true);
  355.                         $this->window->set_skip_pager_hint(true);
  356.                         $this->window->set_keep_above(true);
  357.                         $this->window->set_keep_below(true);
  358.                         $this->window->stick();
  359.                         $this->window->unstick();
  360.                         $this->window->set_decorated(false);
  361.                         break;
  362.  
  363.                 default:
  364.                         throw new Exception ("un supported DesktopGadget type '$type'");
  365.                 }
  366.  
  367.                 $frame = new Frame('darkgreen');
  368.  
  369.                         $vbox = new GtkVbox();
  370.                         $frame->add($vbox);
  371.  
  372.                                 $this->title_bar = new TitleBar($this->config, $title);
  373.                                 $vbox->pack_start($this->title_bar, false, false);
  374.  
  375.                                 $this->panel = new GtkVbox();
  376.                                 $vbox->pack_end($this->panel, true, true);
  377.                                 $this->title_bar->manage($this->panel);
  378.                
  379.  
  380.                 # settings
  381.                 # $this->window->set_size_request( 100, -1 );  # set window size
  382.                 # place window to screen center ; will be overriden at realize with saved (x,y) from config
  383.                 $this->window->set_position(Gtk::WIN_POS_CENTER);
  384.                 # connection tree
  385.                 $this->window->add($frame);
  386.  
  387.                 # terminate
  388.                 $this->window->show_all();
  389.         }
  390.  
  391.         # override composite methods : add, pack_start, pack_end;
  392.         # now add child widget to $this->pannel (a GtkVbox widget)
  393.         public function add($w){
  394.                 $this->pack_start($w);
  395.         }
  396.  
  397.         public function pack_start($w, $expand = true, $fill = true, $padding=0){
  398.                 $this->panel->pack_start($w, $expand, $fill, $padding);
  399.                 $this->window->show_all();
  400.         }
  401.  
  402.         public function pack_end($w, $expand = true, $fill = true, $padding=0){
  403.                 $this->panel->pack_end($w, $expand, $fill, $padding);
  404.                 $this->window->show_all();
  405.         }
  406. }
  407.  
  408.  
  409. $gadget = new DesktopGadget($title='Desktop Gadget');
  410. $gadget->pack_start($clock = new ClockWidget());
  411.  
  412. Gtk::main();
  413.  
  414. ?>

Paste Details

advertising

Update the Post

Either update this post and resubmit it with changes, or make a new post.

You may also comment on this post.

update paste below
details of the post (optional)

Note: Only the paste content is required, though the following information can be useful to others.

Save name / title?

(space separated, optional)



Please note that information posted here will expire by default in one month. If you do not want it to expire, please set the expiry time above. If it is set to expire, web search engines will not be allowed to index it prior to it expiring. Items that are not marked to expire will be indexable by search engines. Be careful with your passwords. All illegal activities will be reported and any information will be handed over to the authorities, so be good.

worth-right
fantasy-obligation