Python: Decide which scrollbar is moving in ScrolledPanel - event-handling

This question continue the question on the link : wxPython Event for ScrolledPanel. I edited the code a little bit so that OnScroll function get the x position of the content's scrollbar and use that to set x position of the header's scrollbar.
My problem is I cannot decide when the horizontal scrollbar is rolled. So my program now has the header's horizontal scrollbar rolled whenever any of the content's scrollbars is rolled while I want the header's h-scrollbar rolled when the content's h-scrollbar is rolled. (Or if anyone can suggest an event triggering by only when scrolling the horizontal bar it will be very good). Thanks ahead.
import wx
from wx.lib.scrolledpanel import ScrolledPanel
header = """
col1 col2 col3 col4 col5"""
text = """
1336 733 1336 4732 1217
5968 4477 1217 5748 4477
1217 5635 4372 1217 5634
4369 1217 5633 4371 217"""
class Test(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, -1, title, size=(300, 200))
self.panel=panel = wx.Panel(self, -1)
vbox = wx.BoxSizer(wx.VERTICAL)
vboxA = wx.BoxSizer(wx.VERTICAL)
hbox = wx.BoxSizer(wx.HORIZONTAL)
self.headerPanel = headerPanel = ScrolledPanel(panel, -1, size=(150,32))
hboxHeader = wx.BoxSizer(wx.HORIZONTAL)
self.headertc = headertc = wx.TextCtrl(headerPanel, -1, header,
size=(500,32),style= wx.TE_READONLY)
headertc.Unbind(wx.EVT_SCROLLWIN)
hboxHeader.Add(headertc,1)
headerPanel.SetSizer(hboxHeader)
headerPanel.SetAutoLayout(1)
headerPanel.SetupScrolling(scroll_y = False)
hbox.Add(headerPanel,1, wx.EXPAND | wx.ALL,0)
vboxA.Add(hbox, 0, wx.EXPAND)
self.textPanel = textPanel = ScrolledPanel(panel, -1, size = (150,150))
textPanel.Bind(wx.EVT_SCROLLWIN, self.OnScroll)
hboxText = wx.BoxSizer(wx.HORIZONTAL)
self.tc = tc = wx.TextCtrl(textPanel, -1, text, size=(500,500),
style=wx.TE_MULTILINE|wx.TE_DONTWRAP| wx.TE_READONLY)
hboxText.Add(tc, 1)
textPanel.SetSizer(hboxText)
textPanel.SetAutoLayout(1)
textPanel.SetupScrolling(scroll_x=True, scroll_y=True)
vboxA.Add(textPanel,1, wx.EXPAND | wx.ALL,0)
vbox.Add(vboxA, 1, wx.EXPAND | wx.ALL)
panel.SetSizer(vbox)
self.Centre()
self.Show(True)
def OnScroll(self, event):
event.Skip()
x= event.GetPosition()
self.headerPanel.Scroll(x,0)
print event.GetEventType()
if __name__ == "__main__":
app = wx.App()
frame = wx.Frame(None, -1)
win = Test(frame, "Test scroll bar")
app.MainLoop()

Use the following condition to check for horizontal scrolling in your scroll handler.
if event.Orientation == wx.SB_HORIZONTAL:

Related

Gmap.Net save image around selected marker

I have an application with GMap.Net showing various markers. I know how to take a screen shot of the current map and markers:
Dim sImageName As String = DateTime.Now.ToString(Format("yyyyMMdd-HHmmss")) & ".png"
Dim ThisMap As New Bitmap(Form2.myMap.Width, Form2.myMap.Height)
Form2.myMap.DrawToBitmap(ThisMap, New Rectangle(0, 0, Form2.myMap.Width, Form2.myMap.Height))
ThisMap.Save(sImagesFolder & sImageName)
What I would like to do is create an image for a selected marker. Instead of the image being the entire map shown on screen, it would center on the marker and show 100 pixels in each direction.
Does anyone know how to do that?
This is what I tried, but it gives me a blank image-- nothing shows up. I feel like this should be working...
Private Sub MyMap_OnMarkerClick(item As GMapMarker, e As Windows.Forms.MouseEventArgs) Handles myMap.OnMarkerClick
SelMarkerX = e.X
SelMarkerY = e.Y
Dim sImageName As String = DateTime.Now.ToString(Format("yyyyMMdd-HHmmss")) & ".png"
Dim ThisMap As New Bitmap(140,100)
myMap.DrawToBitmap(ThisMap, New Rectangle(SelMarkerX - 70, SelMarkerY - 50, 140, 100))
ThisMap.Save(sImagesFolder & sImageName)
End Sub
I just don't get it. If I write:
myMap.DrawToBitmap(ThisMap, New Rectangle(0, 0, 140, 100)
then I get what you might expect. I get the upper left corner of the existing map from 0 to 140 horizontally and 0 to 100 vertically. If I change it to this:
myMap.DrawToBitmap(ThisMap, New Rectangle(10, 0, 140, 100)
then I get 0 to 130 horizontally and not 10 to 140.
Well, I couldn't figure out how to do it with Gmap, so I wondered if I could crop it outside of Gmap and apparently that is common. Here is the code I used.
Dim ThisMap As New Bitmap(Form2.myMap.Width, Form2.myMap.Height)
Form2.myMap.DrawToBitmap(ThisMap, New Rectangle(0, 0, Form2.myMap.Width, Form2.myMap.Height))
ThisMap.Save(sImagesFolder & sImageName)
Dim LocX = SelMarkerX - 160 'x cord. of where crop starts
Dim LocY = SelMarkerY - 120 'y cord. of where crop starts
Dim CropW = 320 'Crop width
Dim CropH = 240 'Crop height
Dim CropRect As New Rectangle(LocX, LocY, CropW, CropH)
Dim OriginalImage = ThisMap
Dim CropImage = New Bitmap(CropRect.Width, CropRect.Height)
Using grp = Graphics.FromImage(CropImage)
grp.DrawImage(OriginalImage, New Rectangle(0, 0, CropRect.Width, CropRect.Height), CropRect, GraphicsUnit.Pixel)
CropImage.Save(sImagesFolder & sImageName)
End Using

add multiple form button scroll bars at once from vba

I need the below macro to reference another sub change event to loop reference to the row number of the scroll bar, i and then adjust the cell Bi . So far I can only get 100 scroll bars to reference only B2
Sub Tester88()
Dim ScrollBar As Object
Dim rng As Range
Dim i As Long
Dim lastRow As Long
lastRow = 99 'Modify as needed this will be the last possible row to add a button
For i = 2 To lastRow Step 4
Set rng = ActiveSheet.Cells(i, 18) 'Column 3, row i
'## Create the button object and assign a variable to represent it
Set ScrollBar = ActiveSheet.ScrollBars.Add(1, 1, 1, 1)
'## use the btn variable to manipulate the button:
With ScrollBar
.Top = rng.Top
.Left = rng.Left
.width = rng.width
.height = rng.RowHeight
.Value = 1
.Min = 1
.Max = 100
.SmallChange = 1
.LargeChange = 10
.LinkedCell = "$B$2"
.Display3DShading = True
End With
Next
End Sub
It looks like you can just put the row in .LinkedCell instead of having it hardcoded. You've set it to a range of 1-100; keep in mind if you are using LinkedCell you are directly controlling the value of the cell, so if you are controlling data that has an existing set of values you need to either set the range (and the value) to the existing value of the cell, or have it as a cell that just shows the scroll bar value and use a formula referencing that cell for the final result you want.+
I've solved this task, so:
Sub Tester88()
Dim ScrollBar As Object
Dim rng As Range
Dim i As Long
Dim lastRow As Long
lastRow = 99 'Modify as needed this will be the last possible row to add a button
For i = 2 To lastRow Step 4
Set rng = ActiveSheet.Cells(i, 13) 'Column 3, row i
'## Create the button object and assign a variable to represent it
Set ScrollBar = ActiveSheet.ScrollBars.Add(1, 1, 1, 1)
'## use the btn variable to manipulate the button:
With ScrollBar
.Top = rng.Top
.Left = rng.Left
.Width = rng.Width
.Height = rng.RowHeight
.Min = 1
.Max = 100
.SmallChange = 1
.LargeChange = 1
.LinkedCell = "B" & i
End With
Next
End Sub

Failing to draw on a Gtk.DrawingArea

I'm not able to draw, i've already read tutorials, i can't find the problem.
I simply have a correct UI drawed by Glade. Then i want to draw, for example 50 drawing areas. So i create a Grid with 50 cells; for each cell there is a vertical box (with a drawing area and a label inside each one). But i can't seen anything drawed.
class collega_GUI:
def __init__(self):
try:
self.__builder = Gtk.Builder()
self.__builder.add_from_file('UI2.glade')
self.__Grid = Gtk.Grid()
self.__Grid.set_margin_left(20)
self.__Grid.set_margin_right(20)
self.__Grid.set_row_spacing(10)
self.__Grid.set_column_spacing(15)
self.__Grid.set_column_homogeneous(True)
self.__GridBox = self.__builder.get_object('box11')
self.__GridBox.pack_end(self.__Grid, 1, 1, 20)
indirizzi_ip = []
for i in range(50):
indirizzi_ip.append(str(i))
cpu_info = {}
for ip in indirizzi_ip:
cpu_info[ip] = dict()
left = 0
right = 0
for ip in indirizzi_ip:
cpu_info[ip]['drawing_area'] = Gtk.DrawingArea()
cpu_info[ip]['drawing_area'].set_size_request(100, 100)
cpu_info[ip]['drawing_area'].set_name(ip)
box = Gtk.VBox(False, 5)
box.add(cpu_info[ip]['drawing_area'])
label = Gtk.Label(ip)
box.add(label)
self.__Grid.attach(box, left, right, 1, 1) #object,left,right,top,bottom
cpu_info[ip]['drawing_area'].connect("draw", self.__draw)
label.show()
cpu_info[ip]['drawing_area'].show() #the draw should start now!
box.show()
# 5 drawing areas in a row
left += 1
if left == 5:
right += 1
left = 0
self.__builder.get_object('Azioni_Window').show()
Gtk.main()
except Exception as xe:
logging.error('%s' % str(xe))
sys.exit()
def __draw(self, widget, context):
context.set_source_rgb(0.9, 0, 0.1) #rosso
context.set_source_rgb(0.1, 0.9, 0) #verde
context.set_source_rgb(0.8, 0.7, 0) #giallo
context.set_source_rgb(0.8, 0.7, 0.8) #inattivo
context.rectangle(0, 0, widget.get_allocated_width(), widget.get_allocated_height())
context.fill()
if __name__=='__main__':
try:
UINX=collega_GUI()
except Exception:
sys.exit()
You're missing
self.__Grid.show()
And hence nothing in the grid is shown.
In general it's easier to just call show_all() on some top-level container rather than trying to remember to show() every individual widget.

How to animate (moving by default) and inanimate (make stationary on tap) colliding objects

Hey Guys I am making a game using corona sdk and so needed help with the lus code. In this program there are bubbles floating across the screen and colliding with each either as well as with the walls of the screen.
I am using 'Collision Filter' for the collisions and the masking operation and it is working well. But in this game I want a bubble to continuously move unless and until it is tapped upon. I thought of using the frame animation to animate each bubble and then add a separate function that will make it stationary when tapped.
But the problem is that at a time only 1 program seems to wrok fine. So,
1) either the bubbles collide, fall down, bounce against wall and eventually rest down.
2) The bubbles continuously keep moving across the screen, without colliding against each other, and instead pass through the other bubbles
What should I do to animate and inanimate(on tapping that bubble) a colliding bubble.
My code is below,
borderCollisionFilter = { categoryBits = 1, maskBits = 2 } -- collides with (4 & 2) only
local borderBodyElement = { bounce=1.0, filter=borderCollisionFilter }
local borderTop = display.newRect( 0, 0, 480, 1 )
borderTop:setFillColor( 0, 0, 0, 0) -- make invisible
physics.addBody( borderTop, "static", borderBodyElement )
local borderBottom = display.newRect( 0, 318, 480, 1 )
borderBottom:setFillColor( 0, 0, 0, 0) -- make invisible
physics.addBody( borderBottom, "static", borderBodyElement )
local borderLeft = display.newRect( 0, 0, 1, 320 )
borderLeft:setFillColor( 0, 0, 0, 0) -- make invisible
physics.addBody( borderLeft, "static", borderBodyElement )
local borderRight = display.newRect( 480, 1, 1, 320 )
borderRight:setFillColor( 0, 0, 0, 0) -- make invisible
physics.addBody( borderRight, "static", borderBodyElement )
--BUBBLES
local bubbleCollisionFilter = { categoryBits = 2, maskBits = 7 }
bubble = {bounce=0.94, radius=18,filter = bubbleCollisionFilter }
local bubble1 = display.newImage( "bubble.png", 50, 50 )
physics.addBody( bubble1, bubble )
local bubble2 = display.newImage( "bubble.png", 100, 230 )
physics.addBody( bubble2, bubble )
local bubble3 = display.newImage( "bubble.png", 180, 200 )
physics.addBody( bubble3, bubble )
local bubble4 = display.newImage( "bubble.png", 90, 30 )
physics.addBody( bubble4, bubble )
--MINIONS
minionCollisionFilter = { categoryBits = 4, maskBits = 2 }
minionBodyElement = { bounce=0.8, filter=minionCollisionFilter }
local c1 = display.newImage("str-minion-small.png")
c1.isVisible=false
physics.addBody( c1, "static", minionBodyElement )
local c2 = display.newImage("str-minion-mid.png")
c2.isVisible=false
physics.addBody( c2, "static", minionBodyElement )
local c3 = display.newImage("str-minion-big.png")
c3.isVisible=false
physics.addBody( c3, "static", minionBodyElement )
--SPAWNING
local function spawnDisk( event )
local phase = event.phase
local volumeBar = display.newLine( 0, 0, 1, 0 )
volumeBar.y = 400
volumeBar.x = 20
local v = 20*math.log(r:getTunerVolume())
local MINTHRESH = 30
local LEFTMARGIN = 20
local v2 = MINTHRESH + math.max (v, -MINTHRESH)
v2 = (display.contentWidth - 1 * LEFTMARGIN ) * v2 / MINTHRESH
volumeBar.xScale = math.max ( 20, v2 )
local l = volumeBar.xScale
local cnt1 = 0
local cnt2 = 0
local cnt3 = 0
local ONE =1
local val = event.numTaps
if "ended" == phase then
if l > 50 and l <=150 then
c1.x=math.random( 10, 450 )
c1.y=math.random( 10, 300 )
physics.addBody( c1, { density=1, radius=10.0 } )
c1.isVisible=true
cnt1= cnt1+ ONE
return c1
elseif l > 100 and l <=250 then
c2.x=math.random( 10, 450 )
c2.y=math.random( 10, 300 )
physics.addBody( c2, { density=2, radius=30.0 } )
c2.isVisible=true
cnt2= cnt2+ ONE
return c2
elseif l >=250 then
c3.x=math.random( 40, 450 )
c3.y=math.random( 40, 300 )
physics.addBody( c3, { density=2, radius=50.0 , bounce=0.0 } )
c3.isVisible=true
cnt3= cnt3+ ONE
return c3
end
end
end
buzzR:addEventListener( "touch", spawnDisk ) --
touch the Button to create minions
Listen for tap events and set objects to static:
http://developer.anscamobile.com/reference/index/bodybodytype
ADDITION: I hadn't bothered to run your code because you claimed the collision masking worked. Now that I actually have tried to run it, I got an error immediately.
First off, you need to require "physics" at the top of your code:
local physics = require("physics")
Then there is a timeout error just a few lines down because you didn't start the physics simulation. The second line of your code should be:
physics.start()
Now I'm going to assume those two lines are actually at the top of your code but you simply didn't paste them here, because I can't imagine you would write a hundred lines of code without ever running it.
However that still leaves more errors. Like, at the bottom of your code it references buzzR but there's no object buzzR defined anywhere.
Please either post code that works or say that you don't have code that works. Sorting through this mess is frustrating.
I have done one application to help with collision masking in Corona SDK, for free of course.
http://developer.anscamobile.com/forum/2011/09/12/coolmasking-take-total-control-over-collision-masking

moving a window widget

I have two windows, one main window which lies behind second window.
How can i move the second window along with main window, when ever the main window
moves. And second window is ordinary window, it will have reference to main window.
Regards,
iSight
I saw this question when I tried to answer this one: How do you save a gui to file in GtkD?
The demo code is modified to answer your question, and here it is:
#!/usr/bin/env python3
from gi.repository import Gtk
import json
import os
class Demo():
def __init__(self):
self.conf_name = 'demo.json'
self.read_config()
self.init_widgets()
self.init_window_position()
def init_widgets(self):
self.window = Gtk.Window()
self.window.set_title('window 1')
self.window.connect('check-resize', self.on_window_check_resize)
self.window.connect('configure-event',
self.on_window_configure_event)
self.window.connect('destroy', self.on_app_exit)
label = Gtk.Label('hello, world')
self.window.add(label)
self.window2 = Gtk.Window()
self.window2.set_title('window 2')
self.window2.connect('configure-event',
self.on_window2_configure_event)
def init_window_position(self):
# restore window size and position.
# we need to read these values from app configuration.
self.window.move(self.conf['window_x'], self.conf['window_y'])
self.window2.move(self.conf['window_x'] + self.conf['pos_diff_x'],
self.conf['window_y'] + self.conf['pos_diff_y'])
self.window.set_default_size(self.conf['window_width'],
self.conf['window_height'])
def read_config(self):
if os.path.isfile(self.conf_name):
with open(self.conf_name) as fh:
self.conf = json.loads(fh.read())
else:
# default configuration.
self.conf = {
'window_x': 100,
'window_y': 100,
'window_width': 320,
'window_height': 240,
# distance between window1 and window2 in x dimention.
'pos_diff_x': 120,
# distance between window1 and window2 in y dimention.
'pos_diff_y': 120,
}
def write_config(self):
with open(self.conf_name, 'w') as fh:
fh.write(json.dumps(self.conf))
def run(self):
self.window.show_all()
self.window2.show_all()
Gtk.main()
def on_app_exit(self, widget):
# new setting is dumped when app exits.
self.write_config()
Gtk.main_quit()
def on_window_check_resize(self, window):
print('check resize')
width, height = self.window.get_size()
print('size: ', width, height)
self.conf['window_width'] = width
self.conf['window_height'] = height
def on_window_configure_event(self, window, event):
print('configure event')
x, y = self.window.get_position()
print('position:', x, y)
self.conf['window_x'] = x
self.conf['window_y'] = y
# now move window2.
self.window2.move(x + self.conf['pos_diff_x'],
y + self.conf['pos_diff_y'])
def on_window2_configure_event(self, window, event):
'''
If window2 is moved by user, pos_diff_x and pos_diff_y need to be
recalculated.
'''
print('window2 configure event')
x2, y2 = self.window2.get_position()
print('position: ', x2, y2)
self.conf['pos_diff_x'] = x2 - self.conf['window_x']
self.conf['pos_diff_y'] = y2 - self.conf['window_y']
if __name__ == '__main__':
demo = Demo()
demo.run()
And a screenshot:
you can connect to the configure-event of your first window and change position of the second window accordingly to x and y coordinates which are coming via GdkEvent structure. Below is a small example:
void configure_callback(GtkWindow *window, GdkEvent *event, gpointer data)
{
int x = event->configure.x;
int y = event->configure.y;
gtk_widget_set_uposition(GTK_WIDGET(data), x+220, y);
}
int main(int argc, char * argv[])
{
gtk_init(&argc, &argv);
GtkWidget *window0 = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window0), "Window 0");
gtk_widget_set_uposition(window0, 20, 40);
GtkWidget *window1 = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window1), "Window 1");
gtk_widget_set_uposition(window1, 240, 40);
g_signal_connect_swapped(G_OBJECT(window0), "destroy",
G_CALLBACK(gtk_main_quit), G_OBJECT(window0));
g_signal_connect(G_OBJECT(window0), "configure-event",
G_CALLBACK(configure_callback), window1);
gtk_widget_show_all(window0);
gtk_widget_show_all(window1);
gtk_main();
return 0;
}
once you move "window 0", "window 1" should change its position accordingly.
hope this helps, regards