Pros:
Instantaneous notification when the table changes
Cons:
When there is a network outage between server and client adapter, the notification will not work anymore, a new registration has to be made.
Tuesday, May 29, 2018
Friday, May 13, 2016
C programming using cmd.exe
Windows provides you command line tools when you install VisualStudio Community 2015 (VS2015). You can use VS2015 up to 30 days trial, and after that you'll get prompt asking you to get license, but you still can use the command line tools.
If you wish to add extra libraries, you need to append the %INCLUDE% and %LIB% variables. To do this just use the SET command. For example, if you want to include Python.h, you do the following:
To compile a C program, VS2015 provides you a command line intepreter called cl. To use it, you need to setup the development environment. Luckily, VS2015 also provides a batch script to do this for you. The script is called VsDevCmd.bat and is located inside <VS2015 installation folder>\Common7\Tools.
The most basic usage of cl is:
cl your_first_program.c
If you wish to add extra libraries, you need to append the %INCLUDE% and %LIB% variables. To do this just use the SET command. For example, if you want to include Python.h, you do the following:
SET LIB=%LIB%%PYTHON_HOME%\libs; SET INCLUDE=%INCLUDE%%PYTHON_HOME%\include;
Sunday, November 2, 2014
GWT 2.3: Display blank column for DatePickerCell
If your Column.getValue returns null, you wouldn't be able to popup DatePickerCell.datePicker since you pass null to its datePicker.setValue method.
Here's my solution:
DatePickerCell<Object, Date> cell = new DatePickerCell(datetimeFormatter) {
@Override
protected void onEnterKeyDown(Context context,
Element parent,
Date value,
NativeEvent event,
ValueUpdater<Date> valueUpdater) {
if (value == null)
value = new Date();
super.onEnterKeyDown(context, parent, value, event, valueUpdater);
}
};
Here's my solution:
DatePickerCell<Object, Date> cell = new DatePickerCell(datetimeFormatter) {
@Override
protected void onEnterKeyDown(Context context,
Element parent,
Date value,
NativeEvent event,
ValueUpdater<Date> valueUpdater) {
if (value == null)
value = new Date();
super.onEnterKeyDown(context, parent, value, event, valueUpdater);
}
};
Friday, July 4, 2014
Java: Comparing date with today's date
Usually in Java, if you want to compare there are three methods (that I know of); using DateFormat; using Calendar; and using milliseconds since epoch. The following is how I do date comparison for each methods (starting from the slowest based on my own tests) with d as the target date:
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
cal.add(Calendar.DATE, -5); // 5 days ago.
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
Date d = cal.getTime();
Date today = sdf.parse(sdf.format(new Date));
boolean isBeforeToday = d.getTime() < today.getTime();
boolean isToday = d.getTime() == today.getTime();
boolean isAfterToday = d.getTime() > today.getTime();
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
// I think you can also use Calendar.before() & Calendar.after()...
boolean isBeforeToday = d.getTime() < cal.getTime().getTime();
boolean isToday = d.getTime() == cal.getTime().getTime();
boolean isAfterToday = d.getTime() > cal.getTime().getTime();
long now = new Date().getTime();
long delta = d.getTime() - now;
boolean isBeforeToday = delta <= -86400000; // 24*60*60*1000, milliseconds in a day
boolean isToday = delta <= 0 && delta > -86400000;
boolean isAfterToday = delta > 0;
NOTE: Don't use this if the time part of java.util.Date is non-zero. :)
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
cal.add(Calendar.DATE, -5); // 5 days ago.
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
Date d = cal.getTime();
DateFormat
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");Date today = sdf.parse(sdf.format(new Date));
boolean isBeforeToday = d.getTime() < today.getTime();
boolean isToday = d.getTime() == today.getTime();
boolean isAfterToday = d.getTime() > today.getTime();
Calendar
This is quite fast, so if you prefer readability, I suggest you choose this.Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
// I think you can also use Calendar.before() & Calendar.after()...
boolean isBeforeToday = d.getTime() < cal.getTime().getTime();
boolean isToday = d.getTime() == cal.getTime().getTime();
boolean isAfterToday = d.getTime() > cal.getTime().getTime();
Milliseconds
I prefer this method, which I believe the fastest. But it's the least readable...long now = new Date().getTime();
long delta = d.getTime() - now;
boolean isBeforeToday = delta <= -86400000; // 24*60*60*1000, milliseconds in a day
boolean isToday = delta <= 0 && delta > -86400000;
boolean isAfterToday = delta > 0;
NOTE: Don't use this if the time part of java.util.Date is non-zero. :)
Friday, December 20, 2013
Fedora 20: Touchscreen doesn't work after lid closed
Fedora 20 was released recently and finally I've got the balls to install it in my new touchscreen laptop (which is preinstalled with Windows 8). The installation step is rather easy, takes me only few steps and I was like "that's it? It's installed?"
It looks nice, but there're some issues with my touchscreen. It appears that touchscreen will not work after I close my laptop lid, or probably when the laptop is put to sleep. So my early assumption is that whatever thing that should be handling the input from the touchscreen is not restarted. I'm almost correct, but the actual reason is that the touchscreen device was not mapped to the output device (i.e. the screen).
To solve this, first you need to know the name of your output device using the following command:
$ xrandr
Screen 0: minimum 320 x 200, current 1366 x 768, maximum 8192 x 8192
LVDS1 connected primary 1366x768+0+0 (normal left inverted right x axis y axis) 344mm x 193mm
1366x768 60.0*+
1024x768 60.0
800x600 60.3 56.2
640x480 59.9
VGA1 disconnected (normal left inverted right x axis y axis)
HDMI1 disconnected (normal left inverted right x axis y axis)
DP1 disconnected (normal left inverted right x axis y axis)
in my case, LVDS1 is my laptop screen. Then you need to know your touchscreen ID using the following command:
$ xinput list
⎡ Virtual core pointer id=2 [master pointer (3)]
⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)]
⎜ ↳ Atmel Atmel maXTouch Digitizer id=11 [slave pointer (2)]
⎜ ↳ ETPS/2 Elantech Touchpad id=14 [slave pointer (2)]
⎣ Virtual core keyboard id=3 [master keyboard (2)]
↳ Virtual core XTEST keyboard id=5 [slave keyboard (3)]
↳ Power Button id=6 [slave keyboard (3)]
↳ Video Bus id=7 [slave keyboard (3)]
↳ Video Bus id=8 [slave keyboard (3)]
↳ Sleep Button id=9 [slave keyboard (3)]
↳ USB Camera id=10 [slave keyboard (3)]
↳ Asus WMI hotkeys id=12 [slave keyboard (3)]
↳ AT Translated Set 2 keyboard id=13 [slave keyboard (3)]
from the output, my touchscreen would be Atmel maxTouch with id 11.
Now that you have both my output and input id, you can now map the input to the out using the following command:
$ xinput --map-to-output 11 LVDS1
Now test your touchscreen, it should've work after you execute the command.
Hope this helps. :)
It looks nice, but there're some issues with my touchscreen. It appears that touchscreen will not work after I close my laptop lid, or probably when the laptop is put to sleep. So my early assumption is that whatever thing that should be handling the input from the touchscreen is not restarted. I'm almost correct, but the actual reason is that the touchscreen device was not mapped to the output device (i.e. the screen).
To solve this, first you need to know the name of your output device using the following command:
$ xrandr
Screen 0: minimum 320 x 200, current 1366 x 768, maximum 8192 x 8192
LVDS1 connected primary 1366x768+0+0 (normal left inverted right x axis y axis) 344mm x 193mm
1366x768 60.0*+
1024x768 60.0
800x600 60.3 56.2
640x480 59.9
VGA1 disconnected (normal left inverted right x axis y axis)
HDMI1 disconnected (normal left inverted right x axis y axis)
DP1 disconnected (normal left inverted right x axis y axis)
in my case, LVDS1 is my laptop screen. Then you need to know your touchscreen ID using the following command:
$ xinput list
⎡ Virtual core pointer id=2 [master pointer (3)]
⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)]
⎜ ↳ Atmel Atmel maXTouch Digitizer id=11 [slave pointer (2)]
⎜ ↳ ETPS/2 Elantech Touchpad id=14 [slave pointer (2)]
⎣ Virtual core keyboard id=3 [master keyboard (2)]
↳ Virtual core XTEST keyboard id=5 [slave keyboard (3)]
↳ Power Button id=6 [slave keyboard (3)]
↳ Video Bus id=7 [slave keyboard (3)]
↳ Video Bus id=8 [slave keyboard (3)]
↳ Sleep Button id=9 [slave keyboard (3)]
↳ USB Camera id=10 [slave keyboard (3)]
↳ Asus WMI hotkeys id=12 [slave keyboard (3)]
↳ AT Translated Set 2 keyboard id=13 [slave keyboard (3)]
from the output, my touchscreen would be Atmel maxTouch with id 11.
Now that you have both my output and input id, you can now map the input to the out using the following command:
$ xinput --map-to-output 11 LVDS1
Now test your touchscreen, it should've work after you execute the command.
Hope this helps. :)
Labels:
does not work,
doesn't work,
failed,
fedora 20,
lid,
map,
not working,
remap,
restart,
sleep,
touch,
touchscreen
Monday, August 5, 2013
Java RMI: Client timeout
Creating a timeout for Java RMI client is important since LocateRegistry.getRegistry would make your application unresponsive when the Java RMI server is not available. To create a timeout at the client-side, I suggest you to use ExecutorService. The following codes is an example how to use it:
Suppose you have your localhost listening on port 1099 for RMI and your server serve an interface
public interface RMIService() {
public String sayHello throws RemoteException;
}
Then at your client app, you do this
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new Callable<Object>() {
@Override
public Object call() throws Exception {
String host = "localhost";
int port = 1099;
RMIService service = (RMIService) LocateRegistry
.getRegistry(host, port).lookup("RMIService");
System.err.println(service.sayHello());
return null;
}
});
try {
future.get(5, TimeUnit.SECONDS);
} catch (InterruptedException | TimeoutException |
ExecutionException e) {
System.err.println(e.getMessage());
}
The above code will try executing the remote method and will throw exception if the lookup time exceeds 5 seconds.
Hope this helps. :)
Suppose you have your localhost listening on port 1099 for RMI and your server serve an interface
public interface RMIService() {
public String sayHello throws RemoteException;
}
Then at your client app, you do this
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new Callable<Object>() {
@Override
public Object call() throws Exception {
String host = "localhost";
int port = 1099;
RMIService service = (RMIService) LocateRegistry
.getRegistry(host, port).lookup("RMIService");
System.err.println(service.sayHello());
return null;
}
});
try {
future.get(5, TimeUnit.SECONDS);
} catch (InterruptedException | TimeoutException |
ExecutionException e) {
System.err.println(e.getMessage());
}
The above code will try executing the remote method and will throw exception if the lookup time exceeds 5 seconds.
Hope this helps. :)
Monday, February 18, 2013
Java EE: Persists entity beans with generated primary key (SQL Server)
In developing an enterprise application in Java EE, sometimes you would come across a database table with auto-generated primary key. If you're using NetBeans to generante entity beans from a database, you would get something like this:
@Entity
@Table(name = "your_table_name")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "YourTableName.findByTheId", ... )})
public class YourTableName implements Serializable {
@Id
@Basic(optional = false)
@NotNull
@Column(name = "the_id")
private Integer theId;
...
}
But if you try to persists an instance of the entity bean, you would get an error and you would not be able to alter your database. This is because when you try to persist the instance you would do this
YourTableName yourTableName = new YourTableName();
yourTableName.setFooBarField("foobar"); //example field in table
em.persists(yourTableName);
You could not set the yourself, since it's suppose to be autogenerated by the database. So, in order to solve this, you have to edit the generated entity beans, by adding GeneratedValue annotation to the primary key variable, and also remove the NotNull annotation, like so:
@Id
@Basic(optional = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "the_id")
private Integer theId;
You have to remove @NotNull since, during persisting, you does not set the value for the primary key. Not removing this would throw an error (at least in my case).
Hope this would help. :)
@Entity
@Table(name = "your_table_name")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "YourTableName.findByTheId", ... )})
public class YourTableName implements Serializable {
@Id
@Basic(optional = false)
@NotNull
@Column(name = "the_id")
private Integer theId;
...
}
But if you try to persists an instance of the entity bean, you would get an error and you would not be able to alter your database. This is because when you try to persist the instance you would do this
YourTableName yourTableName = new YourTableName();
yourTableName.setFooBarField("foobar"); //example field in table
em.persists(yourTableName);
You could not set the yourself, since it's suppose to be autogenerated by the database. So, in order to solve this, you have to edit the generated entity beans, by adding GeneratedValue annotation to the primary key variable, and also remove the NotNull annotation, like so:
@Id
@Basic(optional = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "the_id")
private Integer theId;
You have to remove @NotNull since, during persisting, you does not set the value for the primary key. Not removing this would throw an error (at least in my case).
Hope this would help. :)
Tuesday, February 5, 2013
Java: Base64 Encode
I used this function to encode a string using base64 encoding for my java card applet.
public static String base64Encode(String s) {
String table="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ "abcdefghijklmnopqrstuvwxyz0123456789+/";
String b="";
String r="";
int pad;
for (int c : s.toCharArray()) {
b+=rjust(Integer.toBinaryString(c), 8, "0");
}
for (int i=0; i<b.length(); i+=6) {
r+=table.charAt(Integer.parseInt(ljust(b.substring(i, i+6), 6, "0"), 2));
pad=6-b.substring(i, i+6).length();
switch (pad) {
case 0: r+=""; break;
case 4: r+="=="; break;
case 2: r+="="; break; }
}
return r;
}
Both rjust and ljust that you can find in the function above are custom functions similar to python's rjust and ljust.
public static String base64Encode(String s) {
String table="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ "abcdefghijklmnopqrstuvwxyz0123456789+/";
String b="";
String r="";
int pad;
for (int c : s.toCharArray()) {
b+=rjust(Integer.toBinaryString(c), 8, "0");
}
for (int i=0; i<b.length(); i+=6) {
r+=table.charAt(Integer.parseInt(ljust(b.substring(i, i+6), 6, "0"), 2));
pad=6-b.substring(i, i+6).length();
switch (pad) {
case 0: r+=""; break;
case 4: r+="=="; break;
case 2: r+="="; break; }
}
return r;
}
Both rjust and ljust that you can find in the function above are custom functions similar to python's rjust and ljust.
Monday, January 28, 2013
SQL Server notes
Rename a field (or column) in a table:
EXEC sp_rename 'table_name.old_name', 'new_name', 'COLUMN';
sp_rename is a SQL Server function name.
EXEC sp_rename 'table_name.old_name', 'new_name', 'COLUMN';
sp_rename is a SQL Server function name.
Friday, December 21, 2012
Fedora 17: Open port for TCP connection
To open a port for TCP connection you have to edit /etc/sysconfig/iptables and append the following line before the COMMIT line
-A INPUT -m state --state NEW -m tcp -p tcp --dport <PORT> -j ACCEPT
And then restart the iptables service by executing
service iptables restart
*EDIT*
I created this post before knowing that you could actually use iptables directly as below :P :
# iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport <PORT> -j ACCEPT
You should list your iptables rules first to check whether there's any DROP rule. If your new rule comes after a rule that DROPs any connection on you target port, the port you're trying to open will stay closed. If there's a DROP rule, use -I (insert) instead:
# iptables -I INPUT <rulenum> -m state --state NEW -m tcp -p tcp --dport <PORT> -j ACCEPT
where <rulenum> is the rule index in the chain. and <PORT> is your target port.
-A INPUT -m state --state NEW -m tcp -p tcp --dport <PORT> -j ACCEPT
And then restart the iptables service by executing
service iptables restart
*EDIT*
I created this post before knowing that you could actually use iptables directly as below :P :
# iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport <PORT> -j ACCEPT
You should list your iptables rules first to check whether there's any DROP rule. If your new rule comes after a rule that DROPs any connection on you target port, the port you're trying to open will stay closed. If there's a DROP rule, use -I (insert) instead:
# iptables -I INPUT <rulenum> -m state --state NEW -m tcp -p tcp --dport <PORT> -j ACCEPT
where <rulenum> is the rule index in the chain. and <PORT> is your target port.
Friday, December 14, 2012
Python: Fun with sockets (remote desktop)
Server
Client
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#!/usr/bin/python import os import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((HOST, PORT)) s.listen(5) client, addr = s.accept() cmd = s.recv(1024) try: os.system(cmd) client.sendall("OK") except: client.sendall("FAIL") client.close() |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#!/usr/bin/python import socket import sys s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((HOST, PORT)) s.sendall(sys.argv[1]) data = s.recv(32) print data s.close() print "Received: '%s'"%data |
Wednesday, November 28, 2012
Web programming with python and apache: Webserver index page (index.py)
To use python in a web server instead of php, you need to enable cgi-script in your httpd.conf using
But if you want the script to handle the webserver index page as index.html, index.php does, follow the following steps:
AddHandler cgi-script .cgi .py
and you use
ScriptAlias /cgi-bin/ "/your/own/dir/for/cgi-bin/"
to tell apache the script the location of the scripts to be executed.But if you want the script to handle the webserver index page as index.html, index.php does, follow the following steps:
- Edit your root directory settings to execute cgi scripts and handle .py files by writing:
<Directory /your/root/dir>
Options +ExecCGI
AddHandler cgi-script .cgi .py
</Directory> - Then set your DirectoryIndex as index.py as so:
DirectoryIndex index.py
index.py "Hello, World!"
#!/usr/bin/python
import cgitb
cgitb.enable()
print "Content-Type: text/html;charset=utf-8\r\n" #tells the respond type to the client
print """<html><head><title>FooBarBaz</title></head>
<body>Hello world!</body>
</html>
"""
import cgitb
cgitb.enable()
print "Content-Type: text/html;charset=utf-8\r\n" #tells the respond type to the client
print """<html><head><title>FooBarBaz</title></head>
<body>Hello world!</body>
</html>
"""
Saturday, September 29, 2012
Gtk+ tips: Set value of properties in C
In C, if you want to set the value of certain property of a Gtk+ object, you can do it like so
gtk_<type>_set_<property> (GTK_<TYPE> (var_name), <value>);
For example, to set the title of a GtkWindow to "Hello World", do would write
gtk_window_set_title (GTK_WINDOW (window), "Hello World");
This is fine, but what if you want to set the value of a bunch of properties, say for GtkWindow; "app-paintable", "default-width", "default-height", "resizable", and "modal", most beginner would write:
GtkWidget *window = gtk_window_new ();
gtk_widget_set_app_paintable (window), TRUE);
gtk_window_set_default_size (GTK_WINDOW (window), 100,100);
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
gtk_window_set_modal (GTK_WINDOW (window), TRUE);
Too many characters to type (229 characters excluding spaces and newlines).
I prefer the GObject way to do this task. The following is the code which does the same thing as the code above, but by using g_object_set:
GtkWidget *window = gtk_window_new ();
g_object_set (G_OBJECT (window),
"app-paintable", TRUE,
"default-width", 100, "default-height", 100,
"resizable", FALSE,
"modal", TRUE,
NULL); //the arguments must end with NULL
You have to type much less characters, only 130 characters. You can also remove the G_OBJECT macro from the code above. Moreover, your code would look more beautiful (in my eyes at least). :)
gtk_<type>_set_<property> (GTK_<TYPE> (var_name), <value>);
For example, to set the title of a GtkWindow to "Hello World", do would write
gtk_window_set_title (GTK_WINDOW (window), "Hello World");
This is fine, but what if you want to set the value of a bunch of properties, say for GtkWindow; "app-paintable", "default-width", "default-height", "resizable", and "modal", most beginner would write:
GtkWidget *window = gtk_window_new ();
gtk_widget_set_app_paintable (window), TRUE);
gtk_window_set_default_size (GTK_WINDOW (window), 100,100);
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
gtk_window_set_modal (GTK_WINDOW (window), TRUE);
Too many characters to type (229 characters excluding spaces and newlines).
I prefer the GObject way to do this task. The following is the code which does the same thing as the code above, but by using g_object_set:
GtkWidget *window = gtk_window_new ();
g_object_set (G_OBJECT (window),
"app-paintable", TRUE,
"default-width", 100, "default-height", 100,
"resizable", FALSE,
"modal", TRUE,
NULL); //the arguments must end with NULL
You have to type much less characters, only 130 characters. You can also remove the G_OBJECT macro from the code above. Moreover, your code would look more beautiful (in my eyes at least). :)
Friday, September 14, 2012
Fedora 17: Slow recreate volatile files and directories during boot
One of the reason for this is that there's a broken entry in /etc/fstab. Removing the entry would solve the problem and booting would be faster.
Saturday, July 7, 2012
Chord viewer? Music Viewer?
I created this out of boredom. Everything is drawn using cairo in vala. Now I'm not sure what to do with it. :/
Maybe I should learn about MIDI and then make a tablature editor out of this. :D
Tuesday, June 12, 2012
GTK3: How to create menu button?
In Gtk3, we are provided with GtkMenuToolButton GtkMenuToolButton to show a dropdown menu from a button, but this toolbutton consists of two parts: a button and an additional button that popups a menu when toggled. The first button is useless when we plan to use GtkMenuToolButton as a menu button, thus requires us to find new solution.
There are several methods to create menu button:
What the developer did, is just changing the style class of the GtkMenuBar into button style. That's all. As easy as that! >.<
Code (in python)
menub.get_style_context().add_class("button") #this is the key line.
**UPDATE**
Since Gtk+ 3.6, a native menu button widget, GtkMenuButton has been added.
There are several methods to create menu button:
- Connect the "clicked" or "toggled" signal of a button or toggle button to a callback that pops up a menu. For this method, we need to create a custom positioning function, which is to me a tedious work.
- Customize the GtkMenuToolButton by getting it's child and remove the button part as well as replacing the GtkArrow with another widget.
- Using GtkMenuBar.
Convert GtkMenuBar into Menu Button
This is the simplest way to create a menu button. Before this, I used the second method to come up with a menu button until I updated my Gnome installation to version 3.4 and found out Epiphany 3.4['s] way of implementing this. I don't know why am I so stupid to come up with that method? :(What the developer did, is just changing the style class of the GtkMenuBar into button style. That's all. As easy as that! >.<
Code (in python)
menub = Gtk.MenuBar()
onlyitem = Gtk.MenuItem()
onlyitem_child = Gtk.Button(label = "Menu")
onlyitem.add(onlyitem_child)
onlyitem_child = Gtk.Button(label = "Menu")
onlyitem.add(onlyitem_child)
menu = Gtk.Menu()
mitem1 = Gtk.MenuItem(label = "Item 1")
mitem2 = Gtk.MenuItem(label = "Item 2")
menu.insert(mitem1, 0)
menu.insert(mitem2, 1)
onlyitem.set_submenu(menu)
menub.insert(onlyitem, 0)
**UPDATE**
Since Gtk+ 3.6, a native menu button widget, GtkMenuButton has been added.
Saturday, June 9, 2012
GtkGrid example
I've just upgraded my Fedora 16 installation to Fedora 17 which includes gtk3-3.4. I was working on some hobby project—written in genie—of mine before the upgrade. After upgrading, I tried to compile the source code, but got deprecation errors for GtkHBox and GtkVBox. So I checked devhelp, and was suggested to use GtkBox instead. So I read GtkBox documentation, then I found out that it's also will face the same fate as it's brothers. GtkGrid became the new way. I kinda don't like this change. But anyhow, life must goes on.
Continuing on, GtkGrid is similar to GtkTable, but unlike GtkTable, it stores the child's expand and margin property instead of having its container to give allocation to it. Seems to me to be GtkBuilder or GtkUIManager (I never used this before) friendly.
In genie, If you want to create a box with 3 buttons with the following layout
the old way to do this is
now, with GtkGrid, you had to do like this
Continuing on, GtkGrid is similar to GtkTable, but unlike GtkTable, it stores the child's expand and margin property instead of having its container to give allocation to it. Seems to me to be GtkBuilder or GtkUIManager (I never used this before) friendly.
In genie, If you want to create a box with 3 buttons with the following layout
[<button1:!expand><<<<button2:expand>>>>><button3:!expand>]
the old way to do this is
...
var
box = new HBox(false, 0)
b1 = new Button.with_label("button1")
b2 = new Button.with_label("button2")
b3 = new Button.with_label("button3")
box.pack_start(b1, false, true, 0)
box.pack_start(b2, true, false, 0)
box.pack_start(b3, false, true, 0)
... now, with GtkGrid, you had to do like this
...
var
grid = new Grid
b1 = new Button.with_label("button1")
b2 = new Button.with_label("button2")
b3 = new Button.with_label("button3")
b2.expand = true
grid.attach(b1, 0, 0, 1, 1)
grid.attach(b2, 0, 1, 1, 1)
grid.attach(b3, 0, 2, 1, 1)
...
Tuesday, May 15, 2012
GtkClutterEmbed the Pythonic Way!
The following is a simple clutter-gtk program in python that has an animatable widget. The script is for Gtk+3.0 not Gtk+2.0.
#!/usr/bin/python
from gi.repository import Gtk, Clutter, GtkClutter
storedWidth = 0
storedHeight = 0
def on_clicked(b, actor):
global storedWidth, storedHeight
if actor.get_width() != actor.get_stage().get_width():
storedWidth = actor.get_width()
storedHeight = actor.get_height()
width = actor.get_stage().get_width()
height = actor.get_stage().get_height()
else:
width = storedWidth
height = storedHeight
actor.animatev(Clutter.AnimationMode.EASE_OUT_BOUNCE,
500, ["width", "height"], [width, height])
GtkClutter.init([])
bttn = Gtk.Button("Foobar")
txtv = Gtk.TextView()
scwn = Gtk.ScrolledWindow()
scwn.add(txtv)
scwn.show_all()
bact = GtkClutter.Actor(contents = scwn)
embd = GtkClutter.Embed()
stge = embd.get_stage()
col = Clutter.Color()
col.from_string("#000")
stge.set_color(col)
vbox = Gtk.VBox()
wndw = Gtk.Window(width_request = 400, height_request = 300)
stge.add_actor(bact)
vbox.pack_start(embd, True, True, 0)
vbox.pack_start(bttn, False, True, 0)
wndw.add(vbox)
wndw.show_all()
bttn.connect("clicked", on_clicked, bact)
wndw.connect("destroy", lambda w: Gtk.main_quit())
Gtk.main()
from gi.repository import Gtk, Clutter, GtkClutter
storedWidth = 0
storedHeight = 0
def on_clicked(b, actor):
global storedWidth, storedHeight
if actor.get_width() != actor.get_stage().get_width():
storedWidth = actor.get_width()
storedHeight = actor.get_height()
width = actor.get_stage().get_width()
height = actor.get_stage().get_height()
else:
width = storedWidth
height = storedHeight
actor.animatev(Clutter.AnimationMode.EASE_OUT_BOUNCE,
500, ["width", "height"], [width, height])
GtkClutter.init([])
bttn = Gtk.Button("Foobar")
txtv = Gtk.TextView()
scwn = Gtk.ScrolledWindow()
scwn.add(txtv)
scwn.show_all()
bact = GtkClutter.Actor(contents = scwn)
embd = GtkClutter.Embed()
stge = embd.get_stage()
col = Clutter.Color()
col.from_string("#000")
stge.set_color(col)
vbox = Gtk.VBox()
wndw = Gtk.Window(width_request = 400, height_request = 300)
stge.add_actor(bact)
vbox.pack_start(embd, True, True, 0)
vbox.pack_start(bttn, False, True, 0)
wndw.add(vbox)
wndw.show_all()
bttn.connect("clicked", on_clicked, bact)
wndw.connect("destroy", lambda w: Gtk.main_quit())
Gtk.main()
Friday, November 11, 2011
Tukar fail imej kepada Data URI dan sebaliknya
Data URI adalah satu teknologi yang bagus pada aku kerana semasa menanya (query) sesebuah laman, kita tidak perlu melihat kedalam folder lain untuk mencari fail imej yang berkaitan. Sebaliknya ia telah sedia ada samada dalam fail html atau css. Aku tidak dapat huraikan sepenuhnya kerana bukan bidangku.
Kembali kepada tajuk, aku akan tunjuk cara tukar fail imej kepada data URI kemudian sebaliknya menggunakan python.
Imej kepada data URI
data = open('failpngku.png', 'rb').read().encode('base64').replace('\n','')
dataUri = "data:image/png;base64,%s" % data
Sekarang anda boleh guna kandungan dataUri sebagai argumen untuk attribut src bagi tag img, seperti berikut:
<img src="<kandungan dataUri>">
Yang berikut akan menghasilkan arca smily:
Kod
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAA3NCSVQICAjb4U/gAAAC7UlEQVQokQXBW0/bZhgA4PezjR2HJM6BxA4ODFJIgVIqqqG11aaph+0P7KIXvd8fmCZtP2G9rVrtdt160C6g07SBJqRWRSlbS8foCKJNSAMhGNtJbMfxIU7sr8+DsO0D5UP/FFgXjPf/v3nu2Iqi1h23M5oTxydn+GyB5hagz/lOmmTDCHsYCAew+t/mH64tz83l/b6TyOcB+oF2Uq69O5GN7Oj5mdmrQOa9DkLYsgZ+e6P4q5iL5CdEKpIBHO0pWt8zIrlhQHJTrh3VVa1FLl28GePyFIRNpVYZEbjC/AIAaSg6lxSZRJIBGzzV7XkjfI5iKInt1GobC0s0oWvFndLa/PzMaaOlKYPllY3vvv0eUAA0defO3R9u35OOZF3VClMjml7Uld8IWSlNF1KIwoKYTmQyq2t//fzLQ8AAA+/ujz89fVbMjqVCtEOSbT7VM/Udorz7dmp6tt0sAeiuXfYG8hc3rgJNA6DFBTHOgVR/4dj7zcZrPkG0jg8o3/EA9xjSBWhRJDz5/QG44a5atczGo+X7ZnMd4zqFbRT4Cb6w888WgV0fEMNAgG2JGrIM+TUQUiTV5UXfN7Y7WpkYtGMsQv0B0OHAAfKbr78cJoNwMqrJEkuj0DADlNfYf+F0q/RQJ5Fl+92WpughiiOtIavjE2lesLoeMJlkJPvk8Ypc2e3U/hbP0rzQY1jz3dar9dUiy4zHJi/vlk6mZz9B2Hy6sf7nZ9cvWfqh56rV6na7eWRbaiiMTFM7d+68mJtybDoW/eh9xZi7+Cny2+XGyV5b+/fCx6OB3SCSMVA7kB4FsAC8QN0nQhHPi7XU4dNGfPHzrwiCE9PZMwPEPH+2ScQFaFlARNWtPXPv2DqQCFYAVth8WTmSg8VrtwALCAcGIEeVtnX1rVLfy8RDYiYV5kfANbHvlcoHst4bm7iSHb8SjV/AAYV6AxVBb4h0AQxoV2uVN5p8qLWkAPcj8cSZuUWGG4sJSwCCDymjCx8AL+KIzDGViXEAAAAASUVORK5CYII=">
Hasil
data URI kepada imej
dataSection = dataUri[len('data:image/png;base64,'):]
data = []
while (len(data) > 0):
data.append(dataSection[:76:])
dataSection = dataSection[76:]
ofile = open('output.png', 'wb')
ofile.write('\n'.join(data).decode('base64'))
ofile.close()
Sebuah fail berformat png dengan nama output.png akan terhasil daripada kod di atas, dengan syarat pemboleh ubah dataUri ditugaskan nilai terlebih dahulu.
Kembali kepada tajuk, aku akan tunjuk cara tukar fail imej kepada data URI kemudian sebaliknya menggunakan python.
Imej kepada data URI
data = open('failpngku.png', 'rb').read().encode('base64').replace('\n','')
dataUri = "data:image/png;base64,%s" % data
Sekarang anda boleh guna kandungan dataUri sebagai argumen untuk attribut src bagi tag img, seperti berikut:
<img src="<kandungan dataUri>">
Yang berikut akan menghasilkan arca smily:
Kod
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAA3NCSVQICAjb4U/gAAAC7UlEQVQokQXBW0/bZhgA4PezjR2HJM6BxA4ODFJIgVIqqqG11aaph+0P7KIXvd8fmCZtP2G9rVrtdt160C6g07SBJqRWRSlbS8foCKJNSAMhGNtJbMfxIU7sr8+DsO0D5UP/FFgXjPf/v3nu2Iqi1h23M5oTxydn+GyB5hagz/lOmmTDCHsYCAew+t/mH64tz83l/b6TyOcB+oF2Uq69O5GN7Oj5mdmrQOa9DkLYsgZ+e6P4q5iL5CdEKpIBHO0pWt8zIrlhQHJTrh3VVa1FLl28GePyFIRNpVYZEbjC/AIAaSg6lxSZRJIBGzzV7XkjfI5iKInt1GobC0s0oWvFndLa/PzMaaOlKYPllY3vvv0eUAA0defO3R9u35OOZF3VClMjml7Uld8IWSlNF1KIwoKYTmQyq2t//fzLQ8AAA+/ujz89fVbMjqVCtEOSbT7VM/Udorz7dmp6tt0sAeiuXfYG8hc3rgJNA6DFBTHOgVR/4dj7zcZrPkG0jg8o3/EA9xjSBWhRJDz5/QG44a5atczGo+X7ZnMd4zqFbRT4Cb6w888WgV0fEMNAgG2JGrIM+TUQUiTV5UXfN7Y7WpkYtGMsQv0B0OHAAfKbr78cJoNwMqrJEkuj0DADlNfYf+F0q/RQJ5Fl+92WpughiiOtIavjE2lesLoeMJlkJPvk8Ypc2e3U/hbP0rzQY1jz3dar9dUiy4zHJi/vlk6mZz9B2Hy6sf7nZ9cvWfqh56rV6na7eWRbaiiMTFM7d+68mJtybDoW/eh9xZi7+Cny2+XGyV5b+/fCx6OB3SCSMVA7kB4FsAC8QN0nQhHPi7XU4dNGfPHzrwiCE9PZMwPEPH+2ScQFaFlARNWtPXPv2DqQCFYAVth8WTmSg8VrtwALCAcGIEeVtnX1rVLfy8RDYiYV5kfANbHvlcoHst4bm7iSHb8SjV/AAYV6AxVBb4h0AQxoV2uVN5p8qLWkAPcj8cSZuUWGG4sJSwCCDymjCx8AL+KIzDGViXEAAAAASUVORK5CYII=">
Hasil
data URI kepada imej
dataSection = dataUri[len('data:image/png;base64,'):]
data = []
while (len(data) > 0):
data.append(dataSection[:76:])
dataSection = dataSection[76:]
ofile = open('output.png', 'wb')
ofile.write('\n'.join(data).decode('base64'))
ofile.close()
Sebuah fail berformat png dengan nama output.png akan terhasil daripada kod di atas, dengan syarat pemboleh ubah dataUri ditugaskan nilai terlebih dahulu.
Set proxy melalui terminal
Fedoraku rosak, maka aku terpaksa guna Ubuntu untuk perbaikinya. Malang sekali setelah chroot, aku gagal menghubungi proxy. Melalui carian web, akhirnya aku berjaya temui penyelesaiannya.
Untuk tetapkan proxy http:
export http_proxy="http://<ip_proxy>:<port>"
Untuk tetapkan proxy https:
exprort https_proxy="http://<ip_proxy>:<port>"
Untuk tetapkan proxy http:
export http_proxy="http://<ip_proxy>:<port>"
Untuk tetapkan proxy https:
exprort https_proxy="http://<ip_proxy>:<port>"
Subscribe to:
Posts (Atom)
