[DEVELOPMENT ENVIRONMENT]

* NEW: Traditional Chinese translation made by Timothy Lin.
* BUG: Correctly take the project tabulation size in automatic structure
  completion.
* BUG: Fix the tips of the day language selection.

[EXAMPLES]
* NEW: New MineSweeper example made by Timothy Lin and slightly modified by
  me.

[GB.EVAL.HIGHLIGHT]
* BUG: 'undefined' is a javascript keyword.

[GB.FORM.DIALOG]
* NEW: Take the new Dialog.ShowHidden property into account.

[GB.QT4.EXT]
* BUG: Editor cursor is ensured to be visible when it is visible, not when
  it has just the focus.


git-svn-id: svn://localhost/gambas/trunk@4458 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
Benoît Minisini 2012-02-06 16:48:24 +00:00
parent e20f03d58d
commit 985c1a742d
53 changed files with 11888 additions and 8561 deletions

View File

@ -4051,7 +4051,7 @@ msgstr ""
msgid "Tip of the day #&1"
msgstr ""
#: FTips.class:105
#: FTips.class:107
msgid "Unable to read tip of the day !"
msgstr ""

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -678,9 +678,9 @@ Private Function InsertFunction(sProc As String, sType As String, bPublic As Boo
Editor.Goto(iLine, 0)
If sType Then
Editor.Insert("\n" & sStatic & sPublic & " FUNCTION " & sProc & "(" & sSign & ") AS " & sType & "\n\n" & Space$(Project.TabSize) & "\n\nEND\n")
Editor.Insert("\n" & sStatic & sPublic & " Function " & sProc & "(" & sSign & ") As " & sType & "\n\n" & Space$(Project.TabSize) & "\n\nEnd\n")
Else
Editor.Insert("\n" & sStatic & sPublic & " SUB " & sProc & "(" & sSign & ")\n\n" & Space$(Project.TabSize) & "\n\nEND\n")
Editor.Insert("\n" & sStatic & sPublic & " Sub " & sProc & "(" & sSign & ")\n\n" & Space$(Project.TabSize) & "\n\nEnd\n")
Endif
Editor.End
@ -894,7 +894,7 @@ Private Sub DoStructControlCompletion(iLine As Integer, sLine As String, aSymbol
If Not bUnindent And If sClose And If Not Key.Shift Then Editor.Insert("\n" & sIndent & sClose)
Endif
Editor.End
Editor.Goto(iLine + 1, 2 + Len(sIndent))
Editor.Goto(iLine + 1, Project.TabSize + Len(sIndent))
Stop Event
Return True
Endif

View File

@ -70,6 +70,8 @@ Private Function GetNextTip(Optional bPrev As Boolean) As String
Endif
sLang = System.Language
iPos = RInStr(sLang, ".")
If iPos Then sLang = Left(sLang, iPos - 1)
sFile = "tips/tips." & sLang
If Not Exist(sFile) Then

View File

@ -80,6 +80,7 @@
2 Yannick Butin
2 Sergio Caparrós
2 Jason Scurtu
2 Gaja Sophie Peters
2 Brice Vidal
2 Mathew Rule
2 Daniel Reumerman
@ -87,3 +88,4 @@
1 Louviaux
1 Cooke Dylan
1 Leonardo Suárez Arce
1 Marco Iosif Constantinescu

View File

@ -0,0 +1,442 @@
[WELCOME]
<p> 歡迎使用<b>Gambas</b></p>
<p><b> Gambas</b>是一個基於高級<b>Basic</b>語言直譯器的圖形界面的開發環境。</p>
<p><b> Gambas</b>的目標是使您能輕易而快速地開發出功能強大的程式。但是高效而簡潔的程式還得靠您<b>自己</b>的努力...</p>
<p> 希望您會喜歡!</p>
<p align=right>Beno&icirc;t Minisini<br>
English:<u>gambas@users.sourceforge.net</u><br>
中文:<u>yizhou.he@gmail.com</u></p>
[STARTUP]
<p> 每一個專案都需要有一個<b>啟動類別</b>,這個啟動類別必須定義一個名爲<b>Main</b>的無參數靜態公用方法,它將成爲您的程式的進入點。</p>
<p>定義啟動類別的方法是,用鼠標右鍵點擊工程目錄樹中要設爲啟動類別的類別,並在彈出的右鍵菜單中選中<b>啟動類別</b>。</p>
<p>您不需要在啟動視窗中定義一個<b>Main</b>方法,因爲<b>Gambas</b>己經預定義好了。</p>
<p>這個預定義的啟動方法創建並顯示視窗, 就像<b>Visual Basic&trade;</b>一樣。</p>
[OPEN]
<p> <b>Gambas</b>的<b>OPEN</b>函數和<b>Visual Basic</b>的不太一樣,它並不回傳整數,而是回傳一個<b>檔案</b>物件。</p>
<p>所以,不要使用:</p>
<pre>DIM handle AS Integer
...
OPEN "myfile" FOR READ AS #handle</pre>
<p>而應該使用:</p>
<pre>DIM handle AS File
...
handle = OPEN "myfile" FOR READ</pre>
[CATDIR]
<p> 您知道嗎?您可以使用<b><tt>&/</tt></b>來連接資料夾和檔案名稱,這個運算子會自動處理路徑結尾的<b><tt>/</tt></b>以免重複。</p>
<p>例如:</p>
<pre>PRINT "/home/gambas" &/ ".bashrc"
/home/gambas/.bashrc
PRINT "/home/gambas/" &/ "/tmp" &/ "foo.bar"
/home/gambas/tmp/foo.bar
</pre>
<p>怎麼樣?好用吧!</p>
[EXEC]
<p> 可以將您的整個專案生成一個可執行檔,在<b>專案</b>選單中選擇<b>生成可執行檔</b>。</p>
<p>當<b>Gambas</b>生成可執行檔時,預設會將產生的可執行檔放到您的專案目錄下,可執行檔名和您的專案名稱相同。</p>
[PATH]
<p>
相對路徑在<b>Gambas</b>中有特殊含義,它們總是指向您專案內的文件。
<p>
這裏沒有<b>當前目錄</b>的概念,沒有<b>CHDIR</b>之類的關鍵字來改變它。
<p>
<b>注意:</b>您只能用相對路徑存取專案中的檔案,因爲絕對路徑在您生成可執行檔後就不再可靠了。
[GLOBAL]
<b>Gambas</b>裏不再有<b>全域變數</b>了!
<p>
新的處理方法是,在您的主模組中宣告它們爲<b>PUBLIC</b>(公用類型)。
<p>
如果您的專案中沒有主模組,只有主視窗,那麼宣告它們爲<b>STATIC PUBLIC</b>(靜態公用類型)。
<p>
要存取這些變數,您必須使用主模組名或主視窗名:<tt>MyMainModule.MyGlobalVariable</tt>或
<tt>MyMainForm.MyGlobalVariable</tt>。
[EMPTY]
<p> 要知道一個字串是否爲空,並不需要使用<b>Len()</b>函數,您可以直接測試它,因爲空字串爲<b>FALSE</b>非空字串爲<b>TRUE</b>。</p>
<p>例如,您不需要寫:</p>
<pre>IF Len(MyString) > 0 THEN ...
IF Len(MyString) = 0 THEN ...</pre>
<p>您只需寫:</p>
<pre>IF MyString THEN ...
IF NOT MyString THEN ...</pre>
[TRANSLATE]
<p> <b>Gambas</b>應用程式是可完全翻譯的,條件是您應指定哪些字串是必須要翻譯的。 </p>
<p>用括號將字串括起來就表示該字串是可以被翻譯的。<p>
<pre>PRINT ("我可以被翻譯!")
PRINT "我不能被翻譯!"</pre>
[EVENT]
<p> 每個控制項和每個物件都可以產生事件,都有一個<b>event observer</b>(事件觀察器)和一個事件 <b>group name</b>(組名)。</p>
<p>事件觀察器捕捉物件產生的每一個事件,事件組名將是您用來處理事件的類別名稱的前綴。</p>
<p>預設的事件觀察器是您創建的控制項的容器物件,事件組名是控制項名。</p>
<p>在這種狀況下,一個視窗會接收您在它上面創建的所有控制項發生的事件。</p>
<pre>' Gambas form
DIM hButton AS Button
PUBLIC SUB _new()
&nbsp;&nbsp;hButton = NEW Button(ME) AS "MyButton"
END
PUBLIC SUB MyButton_Click()
&nbsp;&nbsp;PRINT "You have clicked MyButton !"
END
</pre>
[FORM]
<p> 在<b>Gambas</b>中,一個視窗是它自己的事件觀察器,所以您可以直接在它自己的類代碼中管理它的事件(像<b>Resize</b>
<b>Activate</b> ...)。 </p>
<p>這樣,從<b>Visual Basic</b>轉來的新手們就不會迷失方向:-)。</p>
[EMBED]
<p> 在<b>Gambas</b>中,您可以在視窗中嵌入視窗!</p>
<p> 要實現如此強大的功能,只要在初始化視窗物件時將父容器做爲最後一個參數傳給視窗構建函數。</p>
<p>例如:</p>
<p><tt>DIM hForm AS MyDialog<br>
DIM hSuperControl AS MyForm<br><br>
' 創建一個對話框<br>
hForm = NEW MyDialog<br>
' 在此對話框中插入一個視窗<br>
' 注意此視窗需要三個參數,最後一個參數是容器物件<br>
hSuperControl = NEW MyForm(Param1, Param2, MyDialog)<br>
' 移動並改變視窗的大小<br>
hSuperControl.Move(8, 8, 128, 64)<br>
</tt></p>
<p>小心:嵌入後的視窗還是個視窗,它還是它自己的事件觀察器。</p>
[GROUP]
<p> 每個控制項都有一個<b>Group</b>(組)屬性,當此屬性被設置,事件處理名稱的前綴就將是組名而不是控制項名。</p>
<p> 假定您有一個<b>Button</b>(按鈕)名叫<b>btnAction</b>
有一個<b>Click</b>事件處理:</p>
<pre>PUBLIC SUB btnAction_Click()</pre>
<p> 如果您將<b>btnAction</b>的<b>(Group)</b>屬性設爲<b>MyGroup</b>,那麼事件處理從按鈕收到的事件將是:</p>
<pre>PUBLIC SUB MyGroup_Click()</pre>
<p> 此屬性讓您在一個函數中處理不同的控制項的事件,同組中的控制項不需要有相同的類型!</p>
<p><b>註釋:</b> <b>Visual Basic</b>老手可能會認為這個屬性和VB中的<b>控制項陣列</b>相似,但更為強大。:-)</p>
[TAG]
<p> 每一個控制項都有<b>Tag</b>屬性,此屬性是爲編程者設計的,可以是任何您想要的<b>VARIANT</b>(可變類型)數據。</p>
<p>這在使用同組的公用事件處理中區別控制項時非常有用。</p>
[LAST]
<p> <b>LAST</b>關鍵字回傳最近一次發生事件的控制項,當您要寫一個獨立於控制項名的事件處理函式就非常有用。</p>
<p>例如,假設您要寫一個計算器程式。
您定義了十個按鈕,每個數字一個,它們都在一個名叫"Digit"的<b>群組</b>,每個控制項的<b>Tag</b>屬性都被設爲相應的數字。
您的處理程序將會是:</p>
<p><tt>PUBLIC SUB Digit_Click()<br><br>
&nbsp;&nbsp;Display = Display & LAST.Tag<br>
&nbsp;&nbsp;RefreshDisplay<br><br>
END</tt></p>
[LEFT]
<p> 大名鼎鼎的<b>BASIC</b>函數<b>Left$</b>、<b>Right$</b>
和<b>Mid$</b>在<b>Gambas</b>中有了新功能。</p>
<p><b>Left$</b>和<b>Right$</b>的第二個參數是可選的預設值爲1。</p>
<p><tt>Left$("Gambas")</tt> 回傳<tt>"G"</tt><br>
<tt>Right$("Gambas")</tt> 回傳<tt>"s"</tt></p>
<p>第二個參數可以是負數,它的用途是指定反方向上將被切掉的字元個數。</p>
<p><tt>Left$("Gambas", -2)</tt> 回傳<tt>"Gamb"</tt><br>
<tt>Right$("Gambas", -2)</tt> 回傳<tt>"mbas"</tt></p>
<p>相同的,<b>Mid$</b>的第三個參數也可以是負數,指定字串末端將被切掉的字元的個數。</p>
<p><tt>Mid$("Gambas", 2, -2)</tt> 回傳<tt>"amb"</tt>
[OBSERVER]
<p> <b>Observer</b>類別允許您在物件發出事件之前先攔截它。 </p>
<pre>MyTextBox = NEW TextBox(ME) AS "MyTextBox"
MyObserver = NEW Observer(MyTextBox) AS "MyObserver"
...
PUBLIC SUB MyObserver_KeyPress()
DEBUG "Got it first"
END
PUBLIC SUB MyTextBox_KeyPress()
DEBUG "Got it next"
END</pre>
<b>Observer</b>能取消事件,防止物件對外發出事件。
[STRING]
<p> <b>Gambas</b>使用<b>UTF-8</b>字元編碼在記憶體中描述字串。</p>
<p>但是所有的標準<b>Gambas</b>字串函數只處理<b>ASCII</b>碼:
<b>Left</b>、<b>Mid</b>、<b>Right</b>、<b>UCase</b>...
<p>如果想處理UTF-8編碼的字串必須使用<b>String</b>靜態類別的方法,它們的名字和標準字串處理函數完全相同。
<pre>PRINT Len("bébé");; Left$("bébé", 3)
6 bé
PRINT String.Len("bébé");; String.Left("bébé", 3)
4 béb</pre>
[ASSIGNMENT]
<p> <b>Gambas</b>實現了<b>C/C++</b>程序員常用的快捷賦值。
<p><tt>MyVariable += 2</tt> 等價於 <tt>MyVariable = MyVariable + 2</tt>
<p><tt>MyVariable &= "Great"</tt> 等價於 <tt>MyVariable = MyVariable & "Great"</tt>
<p>諸如此類...
[DEBUG]
<p> 可以使用<b>DEBUG</b>語句列印除錯信息到控制台(也就是stderr),用法和<b>PRINT</b>語句完全一樣。
<p>除錯信息前綴有類別名稱,方法名稱和<b>DEBUG</b>語句所在的行號。
<p>除錯信息在生成不包含除錯信息的可執行檔時會被自動刪除。
[TRY]
<p> Gambas使用下面的語句實現錯誤管理
<b>TRY</b><b>ERROR</b><b>CATCH</b>和<b>FINALLY</b>。
<p><b>TRY</b>嘗試執行一個語句而不引發錯誤,隨後使用<b>ERROR</b>語句檢測語句執行中是否發生錯誤。
<pre>TRY MyFile = OPEN "/etc/password" FOR WRITE
IF ERROR THEN PRINT "I cannot do what I want!"</pre>
[CATCH]
<p> Gambas使用下面的語句實現錯誤管理
<b>TRY</b><b>ERROR</b><b>CATCH</b>和<b>FINALLY</b>。
<p><b>CATCH</b>標明函數或者過程中錯誤管理部分(錯誤處理常式)的程式碼的開頭。
<p>當錯誤發生於函數執行的起始到終止之間時,會跳去執行錯誤處理常式的部分。
<p>如果錯誤發生於執行錯誤處理常式期間,會繼續向下一層傳送。錯誤處理常式不保護自己!
<pre>SUB ProcessFile(FileName AS STRING)
...
OPEN FileName FOR READ AS #hFile
...
CLOSE #hFile
CATCH ' 只在發生錯誤時執行
PRINT "Cannot process file "; FileName
END</pre>
[FINALLY]
<p> Gambas使用下面的語句實現錯誤管理
<b>TRY</b><b>ERROR</b><b>CATCH</b>和<b>FINALLY</b>。
<p>在函數的尾部,<b>FINALLY</b>語句引領的代碼被執行,即使在其執行期間有錯誤發生。
<b>FINALLY</b>部分是非必要的。如果函數中有錯誤處理常式,<b>FINALLY</b>部分必須位於處理常式之前。
<p><b>FINALLY</b>部分是非必要的。如果函數中有錯誤處理常式,<b>FINALLY</b>部分必須位於處理常式之前。
<p>如果錯誤發生於<b>FINALLY</b>部分執行期間,錯誤會正常傳送。
<pre>SUB ProcessFile(FileName AS STRING)
...
OPEN FileName FOR READ AS #hFile
...
FINALLY ' 即使有錯誤發生也會被執行
CLOSE #hFile
CATCH ' 只在錯誤發生時執行
PRINT "Cannot print file "; FileName
END</pre>
[OPTIONAL]
<h3>Optional</h3>
<p>在<b>Gambas</b>裡面,函數和程序的參數可以含有選擇性的參數。</p>
<p>定義選擇性參數的方法是在參數名稱面加上 <b><tt>Optional</tt></b> 關鍵字。</p>
<p>您也可以在選擇性參數後面加上預設值,例如:</p>
<pre>Private Sub MyFunction(Param AS String, Optional Optim AS String = "Default")
...
Print "Required: "; param; ", Optional: "; optim
...
End</pre>
[ARRAY]
<h3>For Each</h3>
<p>在 <b>Gambas</b> 裡面,您可以輕易地用迴圈跑過陣列、集合以及其他支援 <b><tt>For Each</tt></b> 的可列舉類別。</p>
<p>例如:</p>
<pre>Dim Xml As New XmlDocument
Dim Node As XmlNode
Dim I As Integer
' Open XML file
Xml.Open("pokus.xml")
' Children is indexed via [i], since it's an array
For I = 0 To Xml.Root.Children.Count - 1
'Attributes are looped via For Each, since it's a collection
For Each Node In Xml.Root.Children[i].Attributes
Print Node.Name;; Node.Value
Next
Next</pre>
[ICON]
<h3>預設圖示</h3>
<p>您可以使用內建的圖示來建構更美觀的圖形程式。這些內建圖示提供多種大小 (<tt>"small"</tt>, <tt>"medium"</tt>, <tt>"large"</tt>,...),您也可以使用絕對大小 (從 16x16 到 256x256)。</p>
<p>例如:
<pre>Image1.Picture = Picture["icon:/32/warning"]
Image2.Picture = Picture["icon:/small/error"]
</pre>
<p><b>警告:</b> 這個功能需要 <tt>gb.form</tt> 元件.
[SETTINGS]
<h3>設定</h3>
<p>如果您需要在程式中儲存一些設定值 (如視窗位置、大小),您很幸運,在 <b>Gambas</b>
中做到這個是易如反掌。 :-)
<p>儲存視窗位置:
<pre>Settings.Write(TheForm)</pre>
<p>回復視窗位置:
<pre>Settings.Read(TheForm)</pre>
儲存設定的方法:
<pre>Settings["Slot/Key"] = Value</pre>
讀取設定的方法:
<pre>Value = Settings["Slot/Key", DefaultValue]</pre>
這些設定將被儲存在 <tt>~/.config/gambas3/&lt;MyApplication&gt;.conf</tt> 中,
<tt>&lt;MyApplication&gt;</tt> 是您的專案名稱。
<p><b>警告:</b> 這個功能需要 <tt>gb.settings</tt> 元件。
[EDITOR]
<p>來點編輯器的提示...</p>
<h3>兩種註解類型</h3>
<pre>' 普通註解</pre>
<b><pre>'' 粗體註解</pre></b>
<p>粗體註解可以用來替程式碼撰寫文件.</p>
<h3>如何使用程式碼片段</h3>
<p>輸入 <tt>main</tt> 然後按下 <b>TAB</b> 鍵. 編輯器將自動插入 static public <tt>Main</tt>
到程式碼中.
<p>輸入 <tt>ds</tt> 然後按下 <b>TAB</b> 鍵. 編輯器將自動插入區域字串變數的宣告, 之後可以立即輸入變數名稱.
<p>程式碼片段可以在開發環境的選項中設定.
[END]
<p> 您己讀完所有的每日提示提示。我希望您己經是 <b>Gambas</b> 的專家了!:-)</p>
<p>如果您想爲Gambas貢獻一份力量請用電子郵件發送新提示到</p>
英文:<p><u>gambas@users.sourceforge.net</u></p>
中文:<p><u>yizhou.he@gmail.com</u></p>
<p>預先感謝!</p>

View File

@ -1,8 +1,8 @@
# Gambas Project File 3.0
# Compiled with Gambas 3.0.0
# Compiled with Gambas 3.0.90
Title=gb.eval.highlight
Startup=Main
Version=3.0.0
Version=3.0.90
VersionFile=1
Component=gb.image
Component=gb.qt4

View File

@ -22,9 +22,10 @@ File[1]="sql/datatypes:57.9"
File[2]="sql/functions:206.0"
File[3]="sql/keywords:543.0"
File[4]="sql/operators:58.0"
Active=5
File[5]=".src/HighlightSQL.module:72.31"
Count=5
Active=6
File[6]=".src/HighlightJavascript.module:16.0"
Count=6
[Watches]
Count=0

View File

@ -15,7 +15,7 @@ Public Sub _init()
$cKeyword[sStr] = 0
Next
For Each sStr In ["false", "null", "this", "true"]
For Each sStr In ["false", "null", "this", "true", "undefined"]
$cKeyword[sStr] = 1
Next

View File

@ -2,7 +2,7 @@ Main
gb.eval.highlight
0
0
3.0.0
3.0.90
gb.image
gb.qt4

View File

@ -1,8 +1,8 @@
# Gambas Project File 3.0
# Compiled with Gambas 3.0.0
# Compiled with Gambas 3.0.90
Title=Enhanced standard dialogs
Startup=Main
Version=3.0.0
Version=3.0.90
VersionFile=1
Component=gb.image
Component=gb.gui

View File

@ -17,6 +17,7 @@ Public Sub Form_Open()
Me.Title = Dialog.Title
dchChoose.Root = "/"
dchChoose.ShowHidden = Dialog.ShowHidden
If Not Dialog.Path Then
dchChoose.SelectedPath = "~"
Else

View File

@ -35,6 +35,7 @@ Public Sub Form_Open()
fchChoose.Multi = $bMulti
'fchChoose.Root = "/"
fchChoose.Filter = Dialog.Filter
fchChoose.ShowHidden = Dialog.ShowHidden
If Dialog.Path Then fchChoose.SelectedPath = Dialog.Path
If fchChoose.Filter.Count > 1 Then

View File

@ -8,7 +8,7 @@ VersionFile=1
Component=gb.image
Component=gb.gui
Component=gb.form
Environment="GB_GUI=gb.gtk"
Environment="GB_GUI=gb.qt4"
TabSize=2
ExecPath=/home/benoit/gambas/examples/Basic/DragNDrop/DragNDrop
Maintainer=benoit

View File

@ -0,0 +1,2 @@
[Desktop Entry]
Icon=./.icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

View File

@ -0,0 +1,53 @@
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2002-11-01 04:27+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: FSettings.form:97
msgid "Cancel"
msgstr "キャンセル"
#: FMain.form:26
msgid "&Change Game Parameters"
msgstr "パラメータを設定(&C)"
#: FMain.form:23
msgid "&Game"
msgstr "ゲーム(&G)"
#: FSettings.form:54
msgid "Height"
msgstr "縦の長さ"
#: .project:1 FMain.form:19
msgid "Minesweeper"
msgstr "マインスイーパ"
#: FSettings.form:71
msgid "Number of mines"
msgstr "地雷の数"
#: FSettings.form:91
msgid "OK"
msgstr "-"
#: FMain.form:30
msgid "&Quit"
msgstr "終了(&Q)"
#: FSettings.form:21
msgid "Settings"
msgstr "設定"
#: FSettings.form:37
msgid "Width"
msgstr "横の長さ"

Binary file not shown.

View File

@ -0,0 +1,52 @@
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2002-11-01 04:27+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: FSettings.form:97
msgid "Cancel"
msgstr "取消"
#: FMain.form:26
msgid "&Change Game Parameters"
msgstr "修改游戏参数(&C)"
#: FMain.form:23
msgid "&Game"
msgstr "游戏"
#: FSettings.form:54
msgid "Height"
msgstr "高度"
#: FMain.form:19 .project:1
msgid "Minesweeper"
msgstr "扫雷"
#: FSettings.form:71
msgid "Number of mines"
msgstr "地雷数"
#: FSettings.form:91
msgid "OK"
msgstr "确定"
#: FMain.form:30
msgid "&Quit"
msgstr "离开(&Q)"
#: FSettings.form:21
msgid "Settings"
msgstr "参数设置"
#: FSettings.form:37
msgid "Width"
msgstr "宽度"

Binary file not shown.

View File

@ -0,0 +1,52 @@
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2002-11-01 04:27+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: .project:1 FMain.form:19
msgid "Minesweeper"
msgstr "踩地雷"
#: FMain.form:23
msgid "&Game"
msgstr "遊戲(&G)"
#: FMain.form:26
msgid "&Change Game Parameters"
msgstr "修改遊戲參數(&C)"
#: FMain.form:30
msgid "&Quit"
msgstr "離開(&Q)"
#: FSettings.form:21
msgid "Settings"
msgstr "設定"
#: FSettings.form:37
msgid "Width"
msgstr "寬度"
#: FSettings.form:54
msgid "Height"
msgstr "高度"
#: FSettings.form:71
msgid "Number of mines"
msgstr "地雷數"
#: FSettings.form:91
msgid "OK"
msgstr "確定"
#: FSettings.form:97
msgid "Cancel"
msgstr "取消"

View File

@ -0,0 +1,15 @@
# Gambas Project File 3.0
# Compiled with Gambas 3.0.90
Title=Minesweeper
Startup=FMain
Icon=image/expr_win.png
Version=3.0.90
VersionFile=1
Component=gb.image
Component=gb.gui
Component=gb.form
Authors="Timothy Lin"
Environment="GB_GUI=gb.qt4"
TabSize=3
Translate=1
Language=en

View File

@ -0,0 +1,248 @@
' Gambas class file
Private img_cover As Picture = Picture.Load("image/cover.png")
Private img_cover_hovered As Picture = Picture.Load("image/coveron.png")
Private img_false As Picture = Picture.Load("image/false.png")
Private img_flag As Picture = Picture.Load("image/flag.png")
Private img_face_normal As Picture = Picture.Load("image/expr_normal.png")
Private img_face_win As Picture = Picture.Load("image/expr_win.png")
Private img_face_lose As Picture = Picture.Load("image/expr_lose.png")
Private img_face_o As Picture = Picture.Load("image/expr_o.png")
Private img_mine As Picture
Private img_num[10] As Picture
Private dlgSettings As FSettings = New FSettings
Private game_width As Integer = 20
Private game_height As Integer = 15
Private game_mines As Integer = game_width * game_height / 10
Private game As MineSweeperGame
Private blocks As PictureBox[]
Private play_time As Integer = 0
Public Sub _new()
' img_num[0] is none, img_num[9] is mine
' img_num[1~8] is the number of adjacent mines
' load number images
Dim i As Integer
Dim a As Integer[]
img_num[0] = Picture.Load("image/empty.png")
img_num[9] = Picture.Load("image/mine.png")
For i = 1 To 8
img_num[i] = Picture.Load("image/number_" & Str(i) & ".png")
Next
img_mine = img_num[9]
btnStatus.Resize(img_face_normal.Width + 10, img_face_normal.Height + 10)
btnStatus.Picture = img_face_normal
Timer1.Enabled = False
End
' ----- Window Events -----
Public Sub Form_Open()
ReDimGame(game_width, game_height, game_mines)
'Me.Maximized = True
End
' Public Sub Form_Resize()
' adjust_components()
' End
Public Sub Block_MouseDown()
Dim index As Integer = Last.Tag
Dim x As Integer = index Mod game_width
Dim y As Integer = index / game_width
If Mouse.Left Then
If game.Status = game.GAME_STARTED And game.GetBlockStatus(x, y) = game.BLOCK_COVERED Then
btnStatus.Picture = img_face_o
Endif
Endif
End
Public Sub Block_MouseUp()
Dim index As Integer = Last.Tag
Dim x As Integer = index Mod game_width
Dim y As Integer = index / game_width
'Message("Clicked (" & x & "," & y & ")")
If game.Status = game.GAME_STARTED Then
btnStatus.Picture = img_face_normal
Endif
' Skip the event if the mouse button is released outside the block it is pressed
If Mouse.X > blocks[0, 0].Width Or Mouse.y > blocks[0, 0].Height Then Return
If Mouse.Right Then
game.ToggleFlag(x, y)
Else If Mouse.Left Then
game.OpenBlock(x, y)
Endif
End
' highlight the block under cursor
Public Sub Block_Enter()
Dim index As Integer = Last.Tag
Dim x As Integer = index Mod game_width
Dim y As Integer = index / game_width
If game.Status = game.GAME_WIN Or game.Status = game.GAME_LOSE Then Return
If game.GetBlockStatus(x, y) = game.BLOCK_COVERED Then
blocks[x, y].Picture = img_cover_hovered
Endif
End
' un-highlight the block under cursor
Public Sub Block_Leave()
Dim index As Integer = Last.Tag
Dim x As Integer = index Mod game_width
Dim y As Integer = index / game_width
If game.Status = game.GAME_WIN Or game.Status = game.GAME_LOSE Then Return
If game.GetBlockStatus(x, y) = game.BLOCK_COVERED Then
blocks[x, y].Picture = img_cover
Endif
End
Public Sub btnStatus_Click()
game.Reset()
End
Public Sub Game_OnStart()
Timer1.Enabled = True
End
Public Sub Game_OnEnd()
Timer1.Enabled = False
End
Public Sub Game_OnRefresh()
Dim x, y As Integer
Dim s As Integer
For x = 0 To game.Width - 1
For y = 0 To game.Height - 1
Select Case game.Status
Case game.GAME_READY
blocks[x, y].Picture = img_cover
btnStatus.Picture = img_face_normal
play_time = 0 ' reset the timer
Timer1.Enabled = False
refresh_timebox()
Case game.GAME_STARTED
s = game.GetBlockStatus(x, y)
If s = game.BLOCK_COVERED Then
blocks[x, y].Picture = img_cover
Else If s = game.BLOCK_FLAGGED Then
blocks[x, y].Picture = img_flag
Else
blocks[x, y].picture = img_num[game.GetBlockNumber(x, y)]
Endif
Case game.GAME_WIN, game.GAME_LOSE
If game.GetBlockStatus(x, y) = game.BLOCK_FLAGGED Then
If game.GetBlockNumber(x, y) = game.NUM_MINE Then
blocks[x, y].Picture = img_flag
Else
blocks[x, y].Picture = img_false
Endif
Else ' the block has been uncovered
blocks[x, y].Picture = img_num[game.GetBlockNumber(x, y)]
Endif
btnStatus.Picture = IIf(game.Status = game.GAME_WIN, img_face_win, img_face_lose)
End Select
Next
Next
refresh_flagbox()
End
Public Sub Timer1_Timer()
play_time += 1
refresh_timebox()
End
Public Sub menuQuit_Click()
Me.Close()
End
Public Sub menuReDim_Click()
dlgSettings.FieldWidth = game_width
dlgSettings.FieldHeight = game_height
dlgSettings.MineCount = game_mines
If dlgSettings.ShowModal() Then
game_width = dlgSettings.FieldWidth
game_height = dlgSettings.FieldHeight
game_mines = dlgSettings.MineCount
ReDimGame(game_width, game_height, game_mines)
Endif
End
' ----- Private Functions -----
' Generate the a width x height board and adjust control positions
Private Sub ReDimGame(width As Integer, height As Integer, mines As Integer)
Dim x, y As Integer
Dim blk As PictureBox
blocks = New PictureBox[width, height]
For x = 0 To width - 1
For y = 0 To height - 1
blk = New PictureBox(panelBoard)
With blk
.Picture = img_cover
.Resize(img_cover.Width, img_cover.Height)
.Move(x * .Width, y * .Height)
.Tag = x + y * width
Object.Attach(blk, Me, "Block")
End With
blocks[x, y] = blk
Next
Next
game = New MineSweeperGame(width, height, mines)
Object.Attach(game, Me, "Game")
game.Reset()
panelBoard.Resize(width * img_cover.Width, height * img_cover.Height)
'adjust_components()
End
' Private Sub adjust_components()
' center_control(panelBoard)
' center_control_horizontal(btnStatus)
' btnStatus.top = panelBoard.top - btnStatus.Height
' TimeBox.Left = 0
' TimeBox.Top = panelBoard.Top - TimeBox.Height
' FlagBox.Left = Me.Width - FlagBox.Width
' FlagBox.Top = panelBoard.Top - FlagBox.Height
' End
Private Sub refresh_timebox()
lblTime.Text = Str(play_time)
End
Private Sub refresh_flagbox()
lblFlags.Text = Str(game.FlagCount)
End
' Center the control in the main window
' Private Sub center_control(c As Control)
' c.Move((Me.Width - c.Width) / 2, (Me.Height - c.Height) / 2)
' End
'
' ' Center the control horizontally in the main window
' Private Sub center_control_horizontal(c As Control)
' c.left = (Me.Width - c.Width) / 2
' End

View File

@ -0,0 +1,78 @@
# Gambas Form File 3.0
{ Form Form
MoveScaled(0,0,81,65)
Text = ("Minesweeper")
Arrangement = Arrange.Vertical
Spacing = True
Margin = True
{ menuGame Menu
Text = ("&Game")
{ menuReDim Menu
Text = ("&Change Game Parameters")
Picture = Picture["icon:/32/edit"]
}
{ menuQuit Menu
Text = ("&Quit")
Picture = Picture["icon:/32/quit"]
}
}
{ HBox1 HBox
MoveScaled(2,2,74,13)
Margin = True
{ PictureBox2 PictureBox
MoveScaled(0,0,11,11)
Picture = Picture["image/clock.png"]
AutoResize = True
Alignment = Align.Center
}
{ lblTime Label
MoveScaled(12,2,12,7)
Font = Font["20"]
AutoResize = True
}
{ Panel2 Panel
MoveScaled(30,3,1,7)
Expand = True
}
{ btnStatus Button
MoveScaled(32,2,7,7)
}
{ Panel3 Panel
MoveScaled(40,3,1,7)
Expand = True
}
{ PictureBox1 PictureBox
MoveScaled(47,0,11,11)
Picture = Picture["image/bigflag.png"]
AutoResize = True
Alignment = Align.Center
}
{ lblFlags Label
MoveScaled(58,5,24,4)
Font = Font["20"]
AutoResize = True
}
}
{ Panel6 Panel
MoveScaled(25,17,10,1)
}
{ Panel4 HBox
MoveScaled(8,19,70,35)
Expand = True
{ Panel1 Panel
MoveScaled(4,7,1,13)
Expand = True
}
{ panelBoard Panel
MoveScaled(10,6,47,25)
}
{ Panel5 Panel
MoveScaled(63,7,1,20)
Expand = True
}
}
{ Timer1 #Timer
#MoveScaled(2,54)
}
}

View File

@ -0,0 +1,66 @@
' Gambas class file
Property FieldWidth As Integer
Property FieldHeight As Integer
Property MineCount As Integer
Public Sub Run() As Boolean
Return Not Me.ShowModal()
End
Public Sub btnOK_Click()
Me.Close(True)
End
Public Sub btnCancel_Click()
Me.Close
End
Public Sub spinWidth_Change()
UpdateMineRange()
spinMines.Value = spinWidth.Value * spinHeight.Value / 10
End
Public Sub spinHeight_Change()
UpdateMineRange()
spinMines.Value = spinWidth.Value * spinHeight.Value / 10
End
Public Sub Form_Open()
UpdateMineRange()
End
Private Sub UpdateMineRange()
spinMines.MinValue = 1
spinMines.MaxValue = spinWidth.Value * spinHeight.Value - 1
End
Private Function FieldWidth_Read() As Integer
Return spinWidth.Value
End
Private Sub FieldWidth_Write(Value As Integer)
spinWidth.Value = Value
End
Private Function FieldHeight_Read() As Integer
Return spinHeight.Value
End
Private Sub FieldHeight_Write(Value As Integer)
spinHeight.Value = Value
End
Private Function MineCount_Read() As Integer
Return spinMines.Value
End
Private Sub MineCount_Write(Value As Integer)
spinMines.Value = Value
End

View File

@ -0,0 +1,71 @@
# Gambas Form File 3.0
{ Form Form
MoveScaled(0,0,61,30)
Text = ("Settings")
Persistent = True
Arrangement = Arrange.Vertical
Spacing = True
Margin = True
{ VBox1 VBox
MoveScaled(1,1,54,22)
{ HBox2 HBox
MoveScaled(2,1,50,6)
{ lblX Label
MoveScaled(1,1,24,4)
Expand = True
AutoResize = True
Text = ("Width")
}
{ spinWidth SpinBox
MoveScaled(14,1,9,4)
MinValue = 5
MaxValue = 50
}
}
{ HBox4 HBox
MoveScaled(2,8,50,6)
{ lblY Label
MoveScaled(1,1,24,4)
Expand = True
AutoResize = True
Text = ("Height")
}
{ spinHeight SpinBox
MoveScaled(26,1,9,4)
MinValue = 5
MaxValue = 25
}
}
{ HBox6 HBox
MoveScaled(2,15,50,6)
{ lblMines Label
MoveScaled(0,1,14,4)
Expand = True
AutoResize = True
Text = ("Number of mines")
}
{ spinMines SpinBox
MoveScaled(37,1,9,4)
}
}
}
{ HBox1 HBox
MoveScaled(1,25,59,4)
Spacing = True
{ Panel1 Panel
MoveScaled(4,0,4,4)
Expand = True
}
{ btnOK Button
MoveScaled(24,0,16,4)
Text = ("OK")
Default = True
}
{ btnCancel Button
MoveScaled(41,0,16,4)
Text = ("Cancel")
Cancel = True
}
}
}

View File

@ -0,0 +1,194 @@
' Gambas class file
Property Read Width As Integer
Property Read Height As Integer
Property Read Status As Integer
Property Read FlagCount As Integer
Event OnStart()
Event OnEnd()
Event OnRefresh()
Public Enum BLOCK_COVERED, BLOCK_FLAGGED, BLOCK_REVEALED
Public Enum GAME_READY, GAME_STARTED, GAME_WIN, GAME_LOSE
Public Enum NUM_MINE = 9
Private $width As Integer
Private $height As Integer
Private $blocks As New Integer[]
Private $status As New Integer[]
Private $mine_count As Integer
Private $flag_count As Integer
Private $covered_block_count As Integer
Private $game_state As Integer
Public Sub _new(w As Integer, h As Integer, n As Integer)
$width = w
$height = h
$mine_count = n
$covered_block_count = 0
$blocks = New Integer[w, h]
$status = New Integer[w, h]
Reset()
End
Public Function Reset()
Dim x, y As Integer
For x = 0 To $width - 1
For y = 0 To $height - 1
$status[x, y] = BLOCK_COVERED
$blocks[x, y] = 0
Next
Next
$game_state = GAME_READY
$covered_block_count = $width * $height
$flag_count = $mine_count
Raise OnRefresh()
End
Public Function GetBlockNumber(x As Integer, y As Integer) As Integer
Return $blocks[x, y]
End
Public Function GetBlockStatus(x As Integer, y As Integer) As Integer
Return $status[x, y]
End
Public Sub OpenBlock(x As Integer, y As Integer)
If $game_state = GAME_READY Then
$game_state = GAME_STARTED
GenerateRandomMines($mine_count, x, y)
Raise OnStart()
Endif
If $game_state = GAME_STARTED And $status[x, y] = BLOCK_COVERED
If $blocks[x, y] = NUM_MINE Then ' stepped on a mine
$game_state = GAME_LOSE
Raise OnEnd()
Else
RecursiveOpen(x, y)
If AllMinesFound() Then
FlagAllMines()
$game_state = GAME_WIN
Raise OnEnd()
Endif
Endif
Endif
Raise OnRefresh()
End
Public Sub ToggleFlag(x As Integer, y As Integer)
If $game_state = GAME_STARTED Then
If $status[x, y] = BLOCK_COVERED Then
$status[x, y] = BLOCK_FLAGGED
$flag_count -= 1
Else If $status[x, y] = BLOCK_FLAGGED Then
$status[x, y] = BLOCK_COVERED
$flag_count += 1
Else
Return
Endif
Raise OnRefresh()
Endif
End
Private Function Width_Read() As Integer
Return $width
End
Private Function Height_Read() As Integer
Return $height
End
Private Function Status_Read() As Integer
Return $game_state
End
Private Function FlagCount_Read() As Integer
Return $flag_count
End
' Generate n mines in the field and guarantee that (nx, ny) does not contain a mine.
Private Sub GenerateRandomMines(n As Integer, nx As Integer, ny As Integer)
Dim i As Integer
Dim x, y As Integer
Dim x2, y2 As Integer
Dim count As Integer = $width * $height
Dim index As Integer
' check if the range is correct
' note that the field should contain at most (w*h-1) mines, not w*h
If n >= count Then Error.Raise("Index out of bounds")
' put n mines into the first blocks, and fill in zero in the rest
For i = 0 To count - 1
x = i Mod $width
y = i / $width
$blocks[x, y] = IIf(i < n, NUM_MINE, 0)
Next
' if a mine is located in (nx, ny), then move the mine to the last block
If $blocks[nx, ny] = NUM_MINE Then Swap $blocks[nx, ny], $blocks[$width - 1, $height - 1]
' shuffle
For i = 0 To count - 1
x = i Mod $width
y = i / $width
x2 = Int(Rnd(0, $width))
y2 = Int(Rnd(0, $height))
If (x = nx And y = ny) Or (x2 = nx And y2 = ny) Then Continue ' skip (nx, ny)
Swap $blocks[x, y], $blocks[x2, y2]
Next
' generate the numbers
For x = 0 To $width - 1
For y = 0 To $height - 1
If $blocks[x, y] = NUM_MINE Then
For x2 = x - 1 To x + 1
For y2 = y - 1 To y + 1
Try IncrementBlockMineCount(x2, y2)
Next
Next
Endif
Next
Next
End
Private Sub IncrementBlockMineCount(x As Integer, y As Integer)
If $blocks[x, y] <> NUM_MINE Then $blocks[x, y] += 1
End
Private Sub RecursiveOpen(x As Integer, y As Integer)
Dim x2, y2 As Integer
If $status[x, y] = BLOCK_COVERED Then
$status[x, y] = BLOCK_REVEALED
$covered_block_count -= 1
If $blocks[x, y] = 0 Then
For x2 = x - 1 To x + 1
For y2 = y - 1 To y + 1
RecursiveOpen(x2, y2)
Next
Next
Endif
Endif
Catch
End
Private Function AllMinesFound() As Boolean
Return $covered_block_count = $mine_count
End
' Automatically mark all mines as flag
Private Sub FlagAllMines()
Dim x, y As Integer
For x = 0 To $width - 1
For y = 0 To $height - 1
If $blocks[x, y] = NUM_MINE Then
$status[x, y] = BLOCK_FLAGGED
Endif
Next
Next
End

View File

@ -0,0 +1,10 @@
FMain
Minesweeper
0
0
3.0.90
gb.image
gb.gui
gb.form

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 849 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 772 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 469 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 579 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 610 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 543 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 547 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 636 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 516 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 683 B

View File

@ -380,7 +380,7 @@ GB_DESC CGslDesc[] =
//GB_CONSTANT("M_SQRT2", "f", "1.41421356237309504880168872421"), /* sqrt(2) */
//GB_CONSTANT("M_SQRT1_2", "f", "0.70710678118654752440084436210"), /* sqrt(1/2) */
//GB_CONSTANT("M_SQRT3", "f", "1.73205080756887729352744634151"), /* sqrt(3) */
//GB_CONSTANT("M_PI", "f", "3.14159265358979323846264338328"), /* pi */
GB_CONSTANT("M_PI", "f", "3.14159265358979323846264338328"), /* pi */
//GB_CONSTANT("M_PI_2", "f", "1.57079632679489661923132169164"), /* pi/2 */
//GB_CONSTANT("M_PI_4", "f", "0.78539816339744830961566084582"), /* pi/4 */
//GB_CONSTANT("M_SQRTPI", "f", "1.77245385090551602729816748334"), /* sqrt(pi) */

View File

@ -2223,7 +2223,7 @@ void GEditor::ensureCursorVisible()
{
int xx, yy;
if (!isUpdatesEnabled() || !hasFocus())
if (!isUpdatesEnabled() || !isVisible())
return;
xx = lineWidth(y, x); // + _charWidth['m'] / 2