Sophie

Sophie

distrib > Mandriva > 9.1 > ppc > by-pkgid > e0521f28751d07a87e3a3d6c7d15a1ac > files > 1948

libgtkmm2.0_1-devel-2.2.1-2mdk.ppc.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>Example Documentation</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head>
<body bgcolor="#ffffff">
<table border="0" width="100%">
<tr>
    <td width="10%" height="40"><img src="../../images/gtkmm_logo.gif" alt="logo" border="0" width="100%" height="100%"/></td>
    <td width="90%" height="40"><img src="../../images/top.gif" alt="top" width="100%" height="40"/></td>
</tr>
</table>
<center>
  <a class="qindex" href="../../index.html">Main Page</a> &nbsp;
  <a href="group__Widgets.html">Widgets</a> &nbsp;
  <a class="qindex" href="namespaces.html"> Namespaces</a> &nbsp;
  <a href="../../tutorial/html/index.html"> Book</a> &nbsp;
</center>
<hr width="100%"/>

<!-- Generated by Doxygen 1.3-rc1 -->
<h1>thread/dispatcher.cc</h1>A <a class="el" href="classGlib_1_1Dispatcher.html">Glib::Dispatcher</a> example.
<p>
<div class="fragment"><pre><span class="comment">/*</span>
<span class="comment"> * Glib::Dispatcher example -- cross thread signalling</span>
<span class="comment"> * by Daniel Elstner  &lt;daniel.elstner@gmx.net&gt;</span>
<span class="comment"> *</span>
<span class="comment"> * Copyright (c) 2002  Free Software Foundation</span>
<span class="comment"> */</span>

<span class="preprocessor">#include &lt;sigc++/class_slot.h&gt;</span>
<span class="preprocessor">#include &lt;glibmm.h&gt;</span>
<span class="preprocessor">#include &lt;<a class="code" href="box_8h.html">gtkmm/box.h</a>&gt;</span>
<span class="preprocessor">#include &lt;<a class="code" href="button_8h.html">gtkmm/button.h</a>&gt;</span>
<span class="preprocessor">#include &lt;<a class="code" href="buttonbox_8h.html">gtkmm/buttonbox.h</a>&gt;</span>
<span class="preprocessor">#include &lt;<a class="code" href="gtk_2gtkmm_2main_8h.html">gtkmm/main.h</a>&gt;</span>
<span class="preprocessor">#include &lt;<a class="code" href="progressbar_8h.html">gtkmm/progressbar.h</a>&gt;</span>
<span class="preprocessor">#include &lt;<a class="code" href="stock_8h.html">gtkmm/stock.h</a>&gt;</span>
<span class="preprocessor">#include &lt;<a class="code" href="gtk_2gtkmm_2window_8h.html">gtkmm/window.h</a>&gt;</span>

<span class="preprocessor">#include &lt;algorithm&gt;</span>
<span class="preprocessor">#include &lt;functional&gt;</span>
<span class="preprocessor">#include &lt;list&gt;</span>


<span class="keyword">namespace</span>
<span class="keyword"></span>{

<span class="keyword">class </span>ThreadProgress : <span class="keyword">public</span> Gtk::ProgressBar
{
<span class="keyword">public</span>:
  ThreadProgress();
  <span class="keyword">virtual</span> ~ThreadProgress();

  <span class="keywordtype">void</span> launch();
  SigC::Signal0&lt;void&gt;&amp; signal_finished();

<span class="keyword">private</span>:
  <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>        progress_;
  <a name="_a1"></a><a class="code" href="classGlib_1_1Dispatcher.html">Glib::Dispatcher</a>    signal_increment_;
  SigC::Signal0&lt;void&gt; signal_finished_;

  <span class="keywordtype">void</span> progress_increment();
  <span class="keywordtype">void</span> thread_function();
};

<span class="keyword">class </span>MainWindow : <span class="keyword">public</span> Gtk::Window
{
<span class="keyword">public</span>:
  MainWindow();
  <span class="keyword">virtual</span> ~MainWindow();

  <span class="keywordtype">void</span> launch_threads();

<span class="keyword">protected</span>:
  <span class="keyword">virtual</span> <span class="keywordtype">bool</span> on_delete_event(GdkEventAny* event);

<span class="keyword">private</span>:
  std::list&lt;ThreadProgress*&gt;  progress_bars_;
  <a name="_a2"></a><a class="code" href="classGtk_1_1Button.html">Gtk::Button</a>*                close_button_;

  <span class="keywordtype">void</span> on_progress_finished(ThreadProgress* progress);
};


ThreadProgress::ThreadProgress()
:
  progress_ (0)
{
  <span class="comment">// Connect to the cross-thread signal.</span>
  signal_increment_.connect(SigC::slot(*<span class="keyword">this</span>, &amp;ThreadProgress::progress_increment));
}

ThreadProgress::~ThreadProgress()
{}

<span class="keywordtype">void</span> ThreadProgress::launch()
{
  <span class="comment">// Create a non-joinable thread -- it's deleted automatically on thread exit.</span>
  <a name="a3"></a><a class="code" href="classGlib_1_1Thread.html#d0">Glib::Thread::create</a>(SigC::slot_class(*<span class="keyword">this</span>, &amp;ThreadProgress::thread_function), <span class="keyword">false</span>);
}

SigC::Signal0&lt;void&gt;&amp; ThreadProgress::signal_finished()
{
  <span class="keywordflow">return</span> signal_finished_;
}

<span class="keywordtype">void</span> ThreadProgress::progress_increment()
{
  <span class="comment">// Use an integer because floating point arithmetic is inaccurate --</span>
  <span class="comment">// we want to finish *exactly* after the 1000th increment.</span>
  ++progress_;

  <span class="keyword">const</span> <span class="keywordtype">double</span> fraction = double(progress_) / 1000.0;
  set_fraction(std::min(fraction, 1.0));

  <span class="keywordflow">if</span>(progress_ &gt;= 1000)
    signal_finished_();
}

<span class="keywordtype">void</span> ThreadProgress::thread_function()
{
  <a name="_a4"></a><a class="code" href="classGlib_1_1Rand.html">Glib::Rand</a> rand;
  <span class="keywordtype">int</span> usecs = 5000;

  <span class="keywordflow">for</span>(<span class="keywordtype">int</span> i = 0; i &lt; 1000; ++i)
  {
    usecs = rand.<a name="a5"></a><a class="code" href="classGlib_1_1Rand.html#a6">get_int_range</a>(std::max(0, usecs - 1000 - i), std::min(20000, usecs + 1000 + i));
    <a name="a6"></a><a class="code" href="namespaceGlib.html#a230">Glib::usleep</a>(usecs);

    <span class="comment">// Tell the GUI thread to increment the progress bar value.</span>
    signal_increment_();
  }
}


MainWindow::MainWindow()
:
  close_button_ (0)
{
  set_title(<span class="stringliteral">"Thread Dispatcher Example"</span>);

  <a name="_a7"></a><a class="code" href="classGtk_1_1VBox.html">Gtk::VBox</a> *<span class="keyword">const</span> vbox = <span class="keyword">new</span> <a class="code" href="classGtk_1_1VBox.html">Gtk::VBox</a>(<span class="keyword">false</span>, 10);
  <a class="code" href="namespaceGtk_1_1Stock.html#a70">add</a>(*Gtk::manage(vbox));
  vbox-&gt;<a name="a8"></a><a class="code" href="classGtk_1_1Container.html#a3">set_border_width</a>(10);

  <span class="keywordflow">for</span>(<span class="keywordtype">int</span> i = 0; i &lt; 5; ++i)
  {
    ThreadProgress *<span class="keyword">const</span> progress = <span class="keyword">new</span> ThreadProgress();
    vbox-&gt;<a name="a9"></a><a class="code" href="classGtk_1_1Box.html#a3">pack_start</a>(*Gtk::manage(progress), Gtk::PACK_SHRINK);
    progress_bars_.push_back(progress);

    progress-&gt;signal_finished().connect(
        SigC::bind(SigC::slot(*<span class="keyword">this</span>, &amp;MainWindow::on_progress_finished), progress));
  }

  <a name="_a10"></a><a class="code" href="classGtk_1_1ButtonBox.html">Gtk::ButtonBox</a> *<span class="keyword">const</span> button_box = <span class="keyword">new</span> <a name="_a11"></a><a class="code" href="classGtk_1_1HButtonBox.html">Gtk::HButtonBox</a>();
  vbox-&gt;<a name="a12"></a><a class="code" href="classGtk_1_1Box.html#a5">pack_end</a>(*Gtk::manage(button_box), Gtk::PACK_SHRINK);

  close_button_ = <span class="keyword">new</span> <a class="code" href="classGtk_1_1Button.html">Gtk::Button</a>(Gtk::Stock::CLOSE);
  button_box-&gt;<a class="code" href="classGtk_1_1Box.html#a3">pack_start</a>(*Gtk::manage(close_button_), Gtk::PACK_SHRINK);
  close_button_-&gt;set_flags(Gtk::CAN_DEFAULT);
  close_button_-&gt;grab_default();
  close_button_-&gt;set_sensitive(<span class="keyword">false</span>);
  close_button_-&gt;signal_clicked().connect(SigC::slot(*<span class="keyword">this</span>, &amp;<a class="code" href="classGtk_1_1Widget.html#a6">Gtk::Widget::hide</a>));

  show_all_children();
  set_default_size(300, -1);
}

MainWindow::~MainWindow()
{}

<span class="keywordtype">void</span> MainWindow::launch_threads()
{
  std::for_each(
      progress_bars_.begin(), progress_bars_.end(),
      std::mem_fun(&amp;ThreadProgress::launch));
}

<span class="keywordtype">bool</span> MainWindow::on_delete_event(GdkEventAny*)
{
  <span class="comment">// Don't allow closing the window before all threads finished.</span>
  <span class="keywordflow">return</span> !progress_bars_.empty();
}

<span class="keywordtype">void</span> MainWindow::on_progress_finished(ThreadProgress* progress)
{
  progress_bars_.remove(progress);

  <span class="comment">// Enable the close button when all threads finished.</span>
  <span class="keywordflow">if</span>(progress_bars_.empty())
    close_button_-&gt;set_sensitive(<span class="keyword">true</span>);
}

} <span class="comment">// anonymous namespace</span>


<span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span>** argv)
{
  <a name="a13"></a><a class="code" href="group__Threads.html#a0">Glib::thread_init</a>();
  <a name="_a14"></a><a class="code" href="classGtk_1_1Main.html">Gtk::Main</a> main_instance (&amp;argc, &amp;argv);

  MainWindow window;

  <span class="comment">// Install a one-shot idle handler to launch the threads</span>
  <span class="comment">// right after the main window has been displayed.</span>
  <a name="a15"></a><a class="code" href="group__MainLoop.html#a8">Glib::signal_idle</a>().connect(
      SigC::bind_return(SigC::slot(window, &amp;MainWindow::launch_threads), <span class="keyword">false</span>));

  <a name="a16"></a><a class="code" href="classGtk_1_1Main.html#d1">Gtk::Main::run</a>(window);

  <span class="keywordflow">return</span> 0;
}

</pre></div><hr><address><small>
Generated for gtkmm by <a href="http://www.doxygen.org/index.html">
Doxygen</a> 1.3-rc1 &copy;&nbsp;1997-2001</small></address>
</body>
</html>